Physics: Move slides along the contact normal with friction, outputs hit/normal in Behaviors, sliding and friction in Colliders and Physics, check total 1057 (#150)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent
d6190ec3ee
commit
e1e8bbdc98
4 files changed
+28
-14
No files matched your search
+1
-1
@@ -108,7 +108,7 @@ shown on the node and editable in the inspector.
|
||||
`Length`, `Distance`, `Normalize`, `Axis input` (four keys → a
|
||||
normalized direction, so diagonals are not faster), `Compare`, `And/Or/Not`, `Key is down`,
|
||||
`Mouse position`, `Mouse button`, `Is hovered`, `Is touching`, `Get velocity`, `Current state` (name and id), `Is in state` (one boolean per state) ·
|
||||
actions `Move` (dx, dy, scale, dt — connect an event's dt for per-second movement; in the object's own axes, which a turned parent turns too), `Set position`, `Spawn`
|
||||
actions `Move` (dx, dy, scale, dt — connect an event's dt for per-second movement; in the object's own axes, which a turned parent turns too; with *Collide with solids* it slides along what it hits, less friction, and outputs `blocked x/y`, `hit` and the contact `normal x/y`, see [Colliders](Colliders)), `Set position`, `Spawn`
|
||||
(asset setting + x/y/z, optional parent → outputs the new object), `Destroy`, `Emit` (starts a particle source over, see *Particles*),
|
||||
`Play sound` / `Stop sound` (see [Sounds](Sounds): the asset says how loud and whether it loops, the node's
|
||||
`volume` multiplies that and its `loop` either leaves it alone or overrules it in either
|
||||
|
||||
+17
-6
@@ -24,12 +24,23 @@ object stands for its collider children, a collider for itself. The geometry liv
|
||||
`src/core/properties/collider.ts` so editor and runtime agree on it.
|
||||
|
||||
**Blocking** is opt-in per movement: the `Move` node has a **Collide with solids** setting
|
||||
(default off). When enabled it moves an object one axis at a time — its own axes, which a turned
|
||||
parent turns as well — and, after each axis, pushes its *solid* colliders back along that axis to
|
||||
just touch any solid collider they ran into (`exitDistance` in `collider.ts`: the travel at which
|
||||
the shapes stop overlapping) — so the other axis still moves and the object slides along walls. Its `blocked x` / `blocked y` outputs tell which
|
||||
axes hit (always `false` with the setting off). In Play a dynamic body that stops the move is pushed
|
||||
along (see [Physics](Physics)). A collider with
|
||||
(default off). When enabled the object's *solid* colliders move along (dx, dy) — in its own axes,
|
||||
which a turned parent turns as well — until one runs into a solid collider; there the object stops
|
||||
flush (`exitDistance` in `collider.ts`: the travel at which the shapes stop overlapping). What is left
|
||||
of the move then goes on **along the surface**: the part into it is dropped, and the part along it
|
||||
is shortened by **friction × the part into it** (Coulomb; the pair's friction is the average of both
|
||||
colliders, a tile counts 0.5). The contact's normal decides which way "along" is, so a circle that
|
||||
runs into an edge rolls up over it, an object pressed onto a slope slides down it unless the pair
|
||||
is rough enough to hold it (friction ≥ tan of the slope), and one pressed against a wall slides
|
||||
along it the slower the harder it presses. Up to four contacts are followed per move (a corner
|
||||
between floor and wall is two). There is no bounce: `Move` sets a distance, not a speed – a
|
||||
dynamic body bounces (see [Physics](Physics)). The outputs: `blocked x` / `blocked y` tell which of
|
||||
the object's own axes something stood against (a floor blocks y, a wall x, a slope each axis the
|
||||
move went along);
|
||||
`hit` whether anything was met; `normal x` / `normal y` which way the first surface faces, in the
|
||||
world, pointing away from it — enough to build a bounce or a wall jump in the graph. All are `false`
|
||||
/ 0 with the setting off. An object without a solid collider of its own moves freely. In Play a
|
||||
dynamic body that stops the move is pushed into the contact (see [Physics](Physics)). A collider with
|
||||
**Trigger (no blocking)** enabled (`isTrigger`, drawn amber instead of green) still produces
|
||||
collision events but never blocks. An overlap that already exists is never resolved (no jolt
|
||||
when objects start stacked or inside a wall) but also never deepened, so such an object can
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ npm run check # typecheck + lint + format:check + tests, the gate CI runs
|
||||
# code is lost (tail's is reported), so a red run reads as green
|
||||
npm run build # writes dist/ and regenerates index.html
|
||||
./build.sh # the same under `set -o pipefail`, for callers that pipe the output
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1055 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
node tools/seed-e2e.mjs && node tools/e2e.mjs # 1057 editor checks, screenshots in /tmp/gm-e2e-*.png
|
||||
GM_STEPS=20 node tools/e2e.mjs # or 1-12, or 6,20 — a subset while working on one step
|
||||
./e2e.sh start [GM_STEPS] # the same run detached, see below
|
||||
./e2e.sh status # live progress, or the last run's result
|
||||
|
||||
+9
-6
@@ -69,9 +69,11 @@ Whether two of them touch is decided by the same overlap test as before – touc
|
||||
count, only overlapping does – the engine only proposes which pairs to test. A placed tilemap is
|
||||
static ground made of its merged solid cells (see [Tilemaps](Tilemaps)). `Move` with
|
||||
*Collide with solids* works as described in [Colliders](Colliders): the object stops flush at what
|
||||
is in its way and slides along it.
|
||||
is in its way and goes on along its surface, less what friction takes – the same friction a
|
||||
dynamic body feels, combined the same way (the average), and the same in Play and the editor run.
|
||||
|
||||
A dynamic body that stops such a move gets **pushed** along the move, as one body meeting another
|
||||
A dynamic body that stops such a move gets **pushed** into the contact – along its normal, so a
|
||||
crate hit at its corner is shoved away from the corner, not along the move – as one body meeting another
|
||||
without bounce: the speed it is pushed with is the move spread over the frame, and how much of it
|
||||
the body takes depends on the two masses – a mover as heavy as a crate shoves it along, a crate
|
||||
forty times heavier hardly shifts (measured: 133 of 161 units in a second, and 0.2). The mover
|
||||
@@ -110,9 +112,10 @@ are placed, because what the editor run moves is saved. The nodes above do nothi
|
||||
|
||||
## What is not there yet
|
||||
|
||||
- `Move` walking up slopes and over steps (#150). Rapier's character controller was measured
|
||||
for it in #147 and not taken: it caught on the seams between boxes lying side by side (10 of 100
|
||||
steps along a floor of 12 crates) and kept a gap of up to 1.7 units, where `Move` catches on
|
||||
nothing and stops flush.
|
||||
- `Move` stepping up onto a ledge, or a limit on how steep a slope it walks up – that is for the
|
||||
graph, with `hit` and `normal` (#150). `Move` does not use Rapier's character controller: in #147
|
||||
it caught on the seams between boxes lying side by side (10 of 100 steps along a floor of 12
|
||||
crates), kept a gap of up to 1.7 units and knows no friction; `Move` works out its contacts itself,
|
||||
in double precision, and slides over the same seams without catching (#150).
|
||||
- The simulation in the editor run (#148), and `On collision stay` with contact data (#149).
|
||||
- Capsules and polygons, collision layers, raycasts, joints, one-way platforms (#144).
|
||||
Reference in new issue
Block a user