public sealed class TerrainColliderSystemGives every terrain in the world a collider: one height-field shape per tile.
As a system
- Phase
- EarlyUpdate
- Writes
- WorldTransform LocalTransform Collider
Remarks
[31 § D10](../../docs/plan/31-terrain-grass-and-trees.md#d10-collision-is-the-heightfield-and-trees-are-collided-within-a-radius), and the call that was missing. Every piece of this path was built and tested and nothing joined them: PhysicsShapes.HeightField registers the Jolt shape, TerrainSamples.FillCollisionSamples produces exactly the span it consumes — metres, row-major, holes as the caller's sentinel — and ITerrainPlacements says where the ground is. So a terrain in a game had no collision at all, in any project, and the symptom was not an error: a character walked onto it and fell through.
⚠ The tile is the unit, and that is [§ D2] rather than an optimisation. One tile is one shape, so a stroke that dirties one tile out of sixteen rebuilds one — and a terrain whose collision was one shape would pause for the whole terrain every time somebody smoothed a ridge.
⚠ Tiles share their boundary samples, so the shapes overlap by one quad. That is the terrain's own arithmetic — TileQuads is TileSamples − 1 — and it is right: a gap of one quad between two height fields is a seam a character falls through, and an overlap is two surfaces at identical heights, which Jolt resolves as one.
⚠ It asks every frame rather than building once, and that is the whole reason it is a system. A .vxterrain is tens of megabytes: ITerrainAssetSource starts a load and answers null for several frames, so a one-shot call at level load gets nothing and builds nothing, silently. Once a terrain has bodies the per-frame cost is one integer compare per tile.
⚠ A tile is rebuilt when its composite changes, without anybody having to say so. RevisionOf counts recomposites, so a stroke that ran through Resolve moves the collider on the next frame. ITerrainColliders — the editor's seam — is the synchronous form of the same job for a tool that cannot wait a frame; Rebuild is what such an adapter calls.
⚠ Holes are watched by count, which is coarse and is the honest bound. TerrainHoles carries no per-tile version and punching one moves no height, so the poll cannot see which tile changed and rebuilds that terrain's tiles when HoleCount moves. A tool that punches and fills within one frame nets zero and is missed; that tool should call Rebuild, which is precise.
⚠ In EarlyUpdate, so the bodies exist before the step. PhysicsSyncSystem creates a Jolt body for every entity with a Collider and a LocalTransform and no RigidBody beside it, which is how a static body is spelled — a height field cannot be dynamic and ShapeDescription.CanBeDynamic says so, so anything else would throw.
Fields and properties (6)
public ITerrainPlacements? PlacementsWhere the terrains are, or null to build nothing.
public float FrictionThe friction every tile's collider is given.
public int TerrainCountHow many terrains have colliders.
public int TileCountHow many tile bodies exist across all of them.
public int RebuildsHow many tiles have been rebuilt since the world started, after their first build.
public SystemAccess Access
Methods (6)
public TerrainColliderSystem(PhysicsScene scene, ITerrainPlacements placements)Gives every terrain in the world a collider: one height-field shape per tile.
public override JobHandle Update(in SystemContext context, JobHandle dependency)Runs the system.
public void Sync()Brings the colliders into step with the placements, once.
public bool Rebuild(Terrain terrain, int tileX, int tileZ)Rebuilds one tile's collision shape now.
public bool Rebuild(Terrain terrain, TerrainRect rect)Rebuilds every tile a rectangle of samples touches.
public bool Forget(Terrain terrain)Destroys a terrain's collision bodies.
Used by (5)
- ArenaThirdPersonShooter
- TerrainColliderSystemTestsVixen.Terrain.Physics.Tests
- PlayTerrainCollidersVixen.Editor.Terrain.Physics
- SculptedGroundTestsVixen.Editor.Terrain.Physics.Tests
- TerrainCollidersVixen.Editor.Terrain.Physics