Physics stage 1b: six new nodes act on dynamic bodies in play (Apply force over the frame, independent of the frame rate, Apply impulse, Set velocity, Set angular velocity, Get velocity, Set gravity for the rest of the run), a node on an object without a dynamic body and moving a dynamic body directly each log a hint once per object, and Move with collision now pushes dynamic bodies with a mass-dependent push while the mover stays flush; Move keeps its own move-and-slide instead of Rapier's character controller, which measurably snags on seams between colliders (#147)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
78899b1ace
commit
0ff3c8b742
10 files changed
+783
-43
No files matched your search
@@ -10,6 +10,7 @@ import {
|
||||
GraphInterpreter,
|
||||
isHandleEnabled,
|
||||
type NodeContext,
|
||||
type PhysicsControl,
|
||||
type SharedState,
|
||||
startStates,
|
||||
type TraceListener,
|
||||
@@ -61,6 +62,9 @@ interface StateChange {
|
||||
source: Instance | null;
|
||||
}
|
||||
|
||||
const NO_DYNAMIC_BODY =
|
||||
'has no dynamic rigidbody, so Apply force, Apply impulse and Set velocity do nothing on it.';
|
||||
|
||||
/** How often state events may cause the next move before the run is called endless. */
|
||||
const MAX_STATE_ROUNDS = 100;
|
||||
|
||||
@@ -565,6 +569,10 @@ export class BehaviorSystem implements System {
|
||||
found.y += dy;
|
||||
return { blockedX: false, blockedY: false };
|
||||
},
|
||||
physics:
|
||||
this.collisions instanceof PhysicsSystem
|
||||
? physicsControl(world, this.collisions, resolve)
|
||||
: undefined,
|
||||
log: (message) => {
|
||||
world.log.push(message);
|
||||
// The `Log` node's whole purpose: the author wants this in the browser console.
|
||||
@@ -599,3 +607,29 @@ export class BehaviorSystem implements System {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/** The physics nodes' way into the played game's engine, with the handles of the graph resolved. */
|
||||
function physicsControl(
|
||||
world: World,
|
||||
physics: PhysicsSystem,
|
||||
resolve: (handle: EntityHandle | null) => Entity | undefined,
|
||||
): PhysicsControl {
|
||||
const act = (handle: EntityHandle, action: (entity: Entity) => boolean): boolean => {
|
||||
const found = resolve(handle);
|
||||
if (!found) return false;
|
||||
if (action(found)) return true;
|
||||
physics.hint(world, found, NO_DYNAMIC_BODY);
|
||||
return false;
|
||||
};
|
||||
return {
|
||||
velocityOf: (handle) => {
|
||||
const found = resolve(handle);
|
||||
const v = found ? physics.velocityOf(found) : null;
|
||||
return found && v ? { ...v, angular: physics.angularVelocityOf(found) ?? 0 } : null;
|
||||
},
|
||||
setVelocity: (handle, x, y) => act(handle, (e) => physics.setVelocity(e, { x, y })),
|
||||
setAngularVelocity: (handle, degrees) => act(handle, (e) => physics.setAngularVelocity(e, degrees)),
|
||||
applyImpulse: (handle, x, y) => act(handle, (e) => physics.applyImpulse(e, { x, y })),
|
||||
setGravity: (x, y) => physics.setGravity(world, { x, y }),
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user