Game.Simulation.AnimalMoveSystem
Assembly:
Namespace: Game.Simulation
Type: class
Base: GameSystemBase
Summary:
AnimalMoveSystem is the simulation system responsible for updating animal movement and transforms. It schedules a Burst-compiled IJobChunk (UpdateTransformDataJob) that processes Animal entities in chunks, updating transform frames, velocities, rotations and animation state. The system supports two movement modes: NormalMove (walking/running/flying/swimming) and StumblingMove (physics-like tumble/stumble). It queries terrain, water surface and net geometry (roads/edges/nodes) to determine ground heights and collisions. The system updates animals only on specific simulation sub-frames (frameIndex % 16 == 5, 9 or 13) and uses a TransformFrame circular buffer (frameIndex / 16 % 4) for interpolation.
Fields
-
private SimulationSystem m_SimulationSystem
System reference for simulation timing and frameIndex. -
private TerrainSystem m_TerrainSystem
Reference to TerrainSystem used to obtain terrain height data. -
private WaterSystem m_WaterSystem
Reference to WaterSystem used to obtain water surface data. -
private Game.Net.SearchSystem m_NetSearchSystem
Reference to net search system providing a NativeQuadTree of net geometry (used to sample ground heights near roads/edges/nodes). -
private EntityQuery m_AnimalQuery
EntityQuery selecting Animal entities that should be updated (ReadOnly, ReadOnly , ReadWrite , Exclude , Exclude ). -
private TypeHandle __TypeHandle
Container for component type & buffer handles used when scheduling the UpdateTransformDataJob. -
private struct UpdateTransformDataJob
(nested)
The Burst-compiled IJobChunk that performs per-chunk animal movement updates. Contains many ComponentTypeHandles, BufferTypeHandles, ComponentLookup and BufferLookup fields, references to TerrainHeightData, WaterSurfaceData and NativeQuadTree for net geometry, and logic to perform NormalMove and StumblingMove. -
private struct TypeHandle
(nested)
Generated helper containing cached ComponentTypeHandle/BufferTypeHandle/ComponentLookup/BufferLookup fields and an __AssignHandles method which binds them to a SystemState.
Properties
- None (no public properties on AnimalMoveSystem).
Constructors
public AnimalMoveSystem()
Default constructor (annotated with [Preserve] in source). Initializes the system instance; real initialization happens in OnCreate().
Methods
protected override void OnCreate()
Creates and caches references to required systems:- SimulationSystem, TerrainSystem, WaterSystem, Game.Net.SearchSystem.
-
Creates the EntityQuery (m_AnimalQuery) that matches animals to update. This method is annotated with [Preserve] in source.
-
protected override void OnUpdate()
Main update entry. Computes a sub-frame index: uint num = m_SimulationSystem.frameIndex % 16. If num == 5 || 9 || 13, the system: - Resets and sets a SharedComponentFilter on m_AnimalQuery with UpdateFrame(num).
- Builds and schedules UpdateTransformDataJob via JobChunkExtensions.ScheduleParallel.
- Retrieves terrain/water/net read handles and registers job readers with the respective systems (m_TerrainSystem.AddCPUHeightReader, m_WaterSystem.AddSurfaceReader, m_NetSearchSystem.AddNetSearchTreeReader).
-
Stores the returned JobHandle into base.Dependency.
-
private void __AssignQueries(ref SystemState state)
Generated helper used by compiler-time setup; here it creates an EntityQueryBuilder (no custom queries beyond the one in OnCreate). -
protected override void OnCreateForCompiler()
Compiler helper that calls __AssignQueries and __TypeHandle.__AssignHandles to bind component handles for the job. -
UpdateTransformDataJob (nested struct) — key methods:
public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
Entrypoint called per chunk. Chooses between StumblingMove (if chunk has Stumbling component) and NormalMove.private void NormalMove(ArchetypeChunk chunk)
Processes standard movement:- Reads Animal, AnimalNavigation, Moving, Transform, PrefabRef, TransformFrame buffers and mesh groups.
- Uses a sub-step factor (4f/15f) for animation/time stepping.
- If animal is roaming, clamps target Y using terrain/water samples depending on target activity (walking, swimming, flying).
- Updates animation via ObjectUtils.UpdateAnimation and writes new TransformFrame (position, velocity, rotation, state & activity).
- Moves transform by velocity and updates rotation to face movement direction.
private void StumblingMove(ArchetypeChunk chunk)
Simulates a physics-like stumble with multiple sub-steps:- Samples object geometry and computes corner world positions.
- Uses GetGroundHeight to obtain the ground heights around the object's corners (terrain + net geometry where applicable).
- Calculates per-corner velocity deltas and angular deltas (CalculatePointVelocityDelta, CalculatePointAngularVelocityDelta) driven by grip, inertia and gravity.
- Integrates velocity & angular velocity with damping and applies to transform and saved TransformFrame.
private float3 CalculatePointVelocityDelta(...)
Computes the velocity correction for a point on the object given ground contact, grip, gravity and time step.private float3 CalculatePointAngularVelocityDelta(...)
Computes angular velocity delta from a linear impulse at a point, dividing by moment of inertia.private void GetGroundHeight(Quad3 cornerPositions, float3 velocity, float timeStep, float gravity, out float4 heights)
Samples terrain heights for each corner, then iterates nearby net geometry (via nested NetIterator + m_NetSearchTree) to adjust heights if road/edge/node geometry is above terrain. Uses NetIterator to check segments, circles and triangles of net geometry to update ground heights.-
void IJobChunk.Execute(...)
Explicit interface implementation forwards to Execute(in ArchetypeChunk...). -
UpdateTransformDataJob.NetIterator (nested inside job)
- Implements INativeQuadTreeIterator
and IUnsafeQuadTreeIterator . - Holds search bounds, corner positions, sampled ground heights and component lookups for net geometry (Composition, Orphan, Node, NodeGeometry, EdgeGeometry, StartNodeGeometry, EndNodeGeometry, NetCompositionData).
- Iterate(...) checks entities in the quad-tree and tests intersections with the search bounds, then calls CheckNode or CheckEdge to inspect geometry and update ground heights.
- CheckSegment, CheckTriangle and CheckCircle helpers compute intersections and update height candidates based on net composition surface heights.
Notes on scheduling and data flow: - The job is Burst-compiled and scheduled in parallel over the m_AnimalQuery. - The job uses read-only references to TerrainHeightData, WaterSurfaceData and the NativeQuadTree for efficient spatial queries. - The system uses UpdateFrame shared component filtering to process different subsets of animals each simulation step (to spread workload). - The TransformFrame buffer index is derived from m_SimulationSystem.frameIndex / 16 % 4 to cycle through frames for interpolation.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Typical AnimalMoveSystem initialization (same as in game code)
m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
m_TerrainSystem = base.World.GetOrCreateSystemManaged<TerrainSystem>();
m_WaterSystem = base.World.GetOrCreateSystemManaged<WaterSystem>();
m_NetSearchSystem = base.World.GetOrCreateSystemManaged<Game.Net.SearchSystem>();
m_AnimalQuery = GetEntityQuery(
ComponentType.ReadOnly<Animal>(),
ComponentType.ReadOnly<UpdateFrame>(),
ComponentType.ReadWrite<TransformFrame>(),
ComponentType.Exclude<Deleted>(),
ComponentType.Exclude<Temp>());
}
If you want to modify or extend animal movement: - Create a system that runs before or after AnimalMoveSystem (use update order attributes or SystemGroup membership). - To change movement rules, consider intercepting or modifying AnimalNavigation/Moving/TransformFrame components before the job runs or scheduling your own IJobChunk that runs on the same query. - Be careful with shared component filters (UpdateFrame) — the system updates only specific subsets on each simulation step. If you schedule your own job, mirror the same filtering strategy for consistency.