object move blocks

debug floaters
This commit is contained in:
azykov@mail.ru
2026-06-12 21:11:35 +03:00
parent 20a4edad5a
commit 209ff3f710
31 changed files with 527 additions and 53 deletions
+2
View File
@@ -2,3 +2,5 @@ export * from './waitConditionAction';
export * from './waitFramesAction';
export * from './waitSecondsAction';
export * from './applyImpulseAction';
export * from './moveToPositionAction';
export * from './moveInDirectionAction';
@@ -0,0 +1,44 @@
import { ScriptAction, type ScriptCoroutineContext, type V3 } from "../../types";
const EPS = 0.05;
export class MoveInDirectionScriptAction extends ScriptAction {
private direction: V3;
private distance: number;
private speed: number;
private traveled: number = 0;
constructor(coroutine: ScriptCoroutineContext, direction: V3, distance: number, speed: number) {
super(coroutine);
const len = Math.sqrt(direction[0] ** 2 + direction[1] ** 2 + direction[2] ** 2);
this.direction = len > 1e-6
? [direction[0] / len, direction[1] / len, direction[2] / len]
: [0, 0, 0];
this.distance = distance;
this.speed = speed;
}
public tick(deltaTime: number): boolean {
const rb = this.coroutine.thisObject.rb();
if (!rb)
return true;
const remaining = this.distance - this.traveled;
if (remaining < EPS)
return true;
const step = Math.min(this.speed * deltaTime, remaining);
const { x, y, z } = rb.translation();
rb.setTranslation({
x: x + this.direction[0] * step,
y: y + this.direction[1] * step,
z: z + this.direction[2] * step,
}, true);
rb.setLinvel({ x: 0, y: 0, z: 0 }, true);
this.traveled += step;
return this.traveled >= this.distance;
}
}
@@ -0,0 +1,44 @@
import { ScriptAction, type ScriptCoroutineContext, type V3 } from "../../types";
export class MoveToPositionScriptAction extends ScriptAction {
private targetPosition: V3;
private speed: number;
constructor(coroutine: ScriptCoroutineContext, targetPosition: V3, speed: number) {
super(coroutine);
this.targetPosition = targetPosition;
this.speed = speed;
}
public tick(deltaTime: number): boolean {
const rb = this.coroutine.thisObject.rb();
if (!rb)
return true;
const { x: px, y: py, z: pz } = rb.translation();
const dx = this.targetPosition[0] - px;
const dy = this.targetPosition[1] - py;
const dz = this.targetPosition[2] - pz;
const distSq = dx * dx + dy * dy + dz * dz;
if (distSq < 0.0001) {
rb.setLinvel({ x: 0, y: 0, z: 0 }, true);
return true;
}
const dist = Math.sqrt(distSq);
const step = this.speed * deltaTime;
if (step >= dist) {
rb.setTranslation({ x: this.targetPosition[0], y: this.targetPosition[1], z: this.targetPosition[2] }, true);
rb.setLinvel({ x: 0, y: 0, z: 0 }, true);
return true;
}
const scale = step / dist;
rb.setTranslation({ x: px + dx * scale, y: py + dy * scale, z: pz + dz * scale }, true);
rb.setLinvel({ x: 0, y: 0, z: 0 }, true);
return false;
}
}
+14 -15
View File
@@ -1,33 +1,32 @@
import type { ScriptAction, ScriptCoroutine } from "../types";
import type { NamedScriptCoroutine, ScriptAction } from "../types";
type CoroutineItem = NamedScriptCoroutine & {
currentAction?: ScriptAction;
};
export class ScriptCoroutines {
private items: { coroutine: ScriptCoroutine, currentAction?: ScriptAction }[] = [];
private items: CoroutineItem[] = [];
public push(coroutines: ScriptCoroutine[]) {
this.items.push(
...coroutines
.map((c) => ({ coroutine: c })),
);
public push(coroutines: NamedScriptCoroutine[]) {
this.items.push(...coroutines.map((c) => ({ ...c })));
}
public tick(deltaTime: number): void {
// execute coroutines one by one and remove the ones that have finished
this.items = this.items
.filter((c) => !this.tickItem(c, deltaTime));
this.items = this.items.filter((c) => !this.tickItem(c, deltaTime));
}
private tickItem(item: { coroutine: ScriptCoroutine, currentAction?: ScriptAction }, deltaTime: number): boolean {
private tickItem(item: CoroutineItem, deltaTime: number): boolean {
if (!item.currentAction) {
try {
const yieldResult = item.coroutine.next();
if (yieldResult.done)
return true; // coroutine exhausted
return true;
item.currentAction = yieldResult.value;
}
catch (err) {
console.error(err);
return true; // coroutine failed to yield an action or return
console.error(`[${item.name}] Script error:`, err);
return true;
}
}
@@ -37,7 +36,7 @@ export class ScriptCoroutines {
item.currentAction = undefined;
}
catch (err) {
console.error(err);
console.error(`[${item.name}] Action error in ${item.currentAction?.constructor.name}:`, err);
item.currentAction = undefined;
}
+5 -8
View File
@@ -36,15 +36,12 @@ export class ScriptGameEventBus {
}
emit(event: string, context: Omit<ScriptContext, keyof ScriptCoroutineContext>): void {
console.log('emitting ' + event);
const coroutines = this.handlers[event]
?.map((h) => {
console.log(`passing ${event} to ${h.handler}(${JSON.stringify(context)}, ${JSON.stringify(h.coroutine)})`);
return h.handler({ ...context, ...h.coroutine });
});
console.log(coroutines);
?.map((h) => ({
owner: h.coroutine.thisObject.id,
name: `${h.coroutine.thisObjectType.name}[${h.coroutine.thisObject.id}]:${event}`,
coroutine: h.handler({ ...context, ...h.coroutine }),
}));
if (coroutines)
this.coroutines.push(coroutines);
+10
View File
@@ -0,0 +1,10 @@
import type { RuntimeGameObjectInstance, V3 } from "../types";
export function positionOfObject(obj: RuntimeGameObjectInstance): V3 {
const t = obj.rb()?.translation();
const result: V3 = t
? [t.x, t.y, t.z]
: [obj.position[0], obj.position[1], obj.position[2]];
return result;
}