#collision
10 items (10 fixes)
Scene.Trace leaves SceneTraceResult.Hitbox null unless the trace calls .UseHitboxes(true). A target that carries model hitboxes but no body collider is invisible to a plain trace: the ray reports no hit at all. Mixing a coarse collider with hitboxes lets the collider shadow them, so a head shot resolves as a body hit.
A PhysicsHullFile node compiled with import_mode HullPerElement treats a material break as an element boundary. Paint two adjoining primitives with a second material and the compiler folds them into one element and builds one convex hull across both. The convex hull of a wall with a hole in it is a solid wall, so every doorway and window built the same way seals shut at once, with no geometry change in the diff. Every offline check stays green, because none of them compile the model. The defect is only visible in the compiled collision, which the editor or an in-engine walk probe can see. Fix by giving physics its own single-material copy of the source mesh, so the render mesh's material list never reaches the physics node, and pin the physics mesh to the render mesh with a lint.
When one character stands on another that uses a collider-less trace mover, standing can't happen physically -- you synthesise it by pinning the rider's feet to the carrier's head each fixed step. Seat at the VISUAL mesh head-top, not the physics capsule height, or the rider sinks into the carrier's head and reads as two merged characters.
A stationary vertical sink at a chunk-corner seam defeats eject, mantle, and even hard-recover (the anchor itself can be buried under an overhang). The terminal escape is a top-out to the chunk surface.
A voxel/heightfield world usually carries two surfaces: a fine render mesh and a coarser collision heightfield. Procedural character-facing geometry (climb grips, standoff nodes) must be sampled from the collision surface, or it floats off the real face the character actually touches.
A multi-hull vmdl authored with per-shape collision_tags does not get those tags at runtime -- a scene ModelCollider overwrites every shape with the GameObject's own tags, so Scene.Trace.WithoutTags can't filter one hull from another. Split the hulls across separate collider GameObjects instead.
A collision rule that keys its direction on the struck object's own velocity is correct for the object that caused the hit and silently backwards for the object that got hit. A car rolling forward at 2 m/s and rammed from behind reads as moving forward, so it dents its nose instead of its rear. Derive the direction from the negated impulse delta-v, which points from the struck face inward for both bodies.
A 'walk up the parent chain to the first ancestor tagged X' resolver silently breaks the moment any later pass tags a descendant with the same tag: the walk stops on the nearest match, not the intended root. Resolve identity against an authoritative roster instead, especially when the tag is also used for physics filtering.
When a continuous-float render surface sits over a quantized-step collision mesh, every quantize boundary becomes an invisible vertical wall the player hits but cannot see.
A zero-radius Scene.Trace.Ray passes straight through coarse voxel ModelColliders and returns Hit=false. Sweep a thin sphere (.Radius(...)) and it hits.