Skip to content

Game.Simulation.HumanMoveSystem

Assembly: Game
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
HumanMoveSystem is an ECS system responsible for updating humanoid (pedestrian) entities' transform frames each simulation update. It schedules a Burst-compiled IJobChunk (UpdateTransformDataJob) that processes humans in two modes: normal walking/moving (including animation updates and steering) and stumbling/falling (physics-like integration with ground sampling and angular velocity). The system queries required world systems (SimulationSystem, TerrainSystem, Game.Net.SearchSystem), sets up an entity query filtered by UpdateFrame index, and manages job dependencies with terrain and net-search read locks.


Fields

  • private SimulationSystem m_SimulationSystem
    Used to read the current simulation frame index and derive transform frame indices. Obtained from World in OnCreate.

  • private TerrainSystem m_TerrainSystem
    Provides TerrainHeightData used when sampling ground heights for stumbling physics and ground collision checks.

  • private Game.Net.SearchSystem m_NetSearchSystem
    Provides a NativeQuadTree representing net geometry (roads, nodes, edges). Used by the job's NetIterator to detect nearby net pieces that affect ground heights.

  • private EntityQuery m_HumanQuery
    EntityQuery that selects human entities updated this frame: ReadOnly, ReadOnly (shared filter), ReadWrite, and excludes Deleted and Temp components.

  • private TypeHandle __TypeHandle
    Generated struct holding ComponentTypeHandle, BufferTypeHandle and ComponentLookup handles used for job scheduling. Populated in OnCreateForCompiler and used to get the handles when scheduling the job.

  • (Nested) UpdateTransformDataJob (BurstCompile)
    A large IJobChunk that does the per-chunk work. Implements movement, animation updates, and stumbling physics. Contains an inner NetIterator struct used to query nearby net geometry and calculate ground heights where needed.

  • (Nested) UpdateTransformDataJob.NetIterator
    Implements INativeQuadTreeIterator to iterate the net search tree and compute ground heights for a Quad3 of corner positions (used by stumbling logic).

  • (Nested) TypeHandle
    Contains strongly-typed component/buffer lookups and an __AssignHandles method used to initialize them from a SystemState.

Properties

  • None public. The system uses internal TypeHandle and private fields to store handles and systems.

Constructors

  • public HumanMoveSystem()
    Default constructor (has [Preserve] attribute in the compiled class). The system relies on OnCreate to initialize required systems and queries.

Methods

  • protected override void OnCreate()
    Initializes references to world systems and sets up the human entity query:
  • m_SimulationSystem = World.GetOrCreateSystemManaged()
  • m_TerrainSystem = World.GetOrCreateSystemManaged()
  • m_NetSearchSystem = World.GetOrCreateSystemManaged()
  • m_HumanQuery = GetEntityQuery(ReadOnly(), ReadOnly(), ReadWrite(), Exclude(), Exclude())

This prepares the system to filter humans by the UpdateFrame shared component (frame index mod).

  • protected override void OnUpdate()
    Main update logic:
  • Computes a shared UpdateFrame index from the simulation frame index (frameIndex % 16).
  • Resets and sets the shared component filter of m_HumanQuery to only process humans for the current UpdateFrame.
  • Builds and schedules UpdateTransformDataJob (Burst-compiled IJobChunk) using component type handles and lookups pulled from __TypeHandle via InternalCompilerInterface.Get* methods.
  • Retrieves a NativeQuadTree from m_NetSearchSystem with a read-only dependency (dependencies).
  • Passes TerrainHeightData from m_TerrainSystem into the job.
  • Registers the returned job handle with m_TerrainSystem.AddCPUHeightReader and m_NetSearchSystem.AddNetSearchTreeReader to inform those systems that a reader is active.
  • Assigns the scheduled job handle to base.Dependency.

The scheduled job does the per-entity movement and animation updates (normal move) or multi-substep stumbling integration (stumbling move).

  • private void __AssignQueries(ref SystemState state)
    Generated helper used at compile-time to assign up-front queries. In this compiled variant it performs a placeholder EntityQueryBuilder call (generated code pattern).

  • protected override void OnCreateForCompiler()
    Compiler-helper method that calls __AssignQueries and __TypeHandle.__AssignHandles to initialize handles for the generated code path.

  • TypeHandle.__AssignHandles(ref SystemState state)
    Initializes all ComponentTypeHandle, BufferTypeHandle and ComponentLookup/BufferLookup fields from a SystemState so the job can obtain proper handles when scheduled.

  • (Nested Job) UpdateTransformDataJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Entry point for IJobChunk. Chooses between StumblingMove and NormalMove based on the presence of the Stumbling component on the chunk.

  • NormalMove(ArchetypeChunk):

    • Reads arrays: Human, CurrentVehicle, HumanNavigation, Moving, Transform, PrefabRef, TransformFrame buffer and MeshGroup buffer.
    • Advances animation using ObjectUtils.UpdateAnimation, computes target direction and velocity, clamps speed, updates transform position/rotation, writes new TransformFrame into the circular transform frame buffer indexed by the system frame index (m_TransformFrameIndex).
    • Handles activity-based prop selection (GetPropID) if the human is interacting with a vehicle's activity location.
  • StumblingMove(ArchetypeChunk):

    • Performs multi-substep (e.g., 4 substeps) physics-like integration:
    • Samples terrain heights at multiple corner positions (GetGroundHeight).
    • Uses NetIterator to include net geometry (roads/edges/nodes) as additional ground height influences.
    • Calculates per-corner velocity deltas and angular velocity deltas, applies damping, integrates angular velocity into rotation (quaternion axis-angle), and integrates position.
    • Writes a single TransformFrame for the current transform frame index.
  • GetGroundHeight:

    • Samples terrain heights for the four corners via TerrainUtils.SampleHeight.
    • Builds a NetIterator with bounds expanded by predicted vertical motion to collect net geometry intersecting the search bounds.
    • The NetIterator inspects nearby nodes, edges and compositions, checking segments and circles to determine potential ground contact heights from net prefabs (e.g., sidewalks, road surfaces) and selects the highest valid ground heights per corner.
  • Other helpers:

    • CalculatePointVelocityDelta, CalculatePointAngularVelocityDelta compute local deltas for the stumbling integrator.
    • GetPropID chooses an AnimatedPropID for certain activities (enter/exit vehicle) when an activity-location prop exists.
  • (Nested) UpdateTransformDataJob.NetIterator.Intersect/Iterate/CheckNode/CheckEdge/CheckSegment/CheckCircle/CheckTriangle
    Iterator logic to test geometry bounds vs. the job's corner bounds, sample net composition surface heights and update corner ground height candidates.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
    m_TerrainSystem = base.World.GetOrCreateSystemManaged<TerrainSystem>();
    m_NetSearchSystem = base.World.GetOrCreateSystemManaged<Game.Net.SearchSystem>();
    m_HumanQuery = GetEntityQuery(
        ComponentType.ReadOnly<Human>(),
        ComponentType.ReadOnly<UpdateFrame>(),
        ComponentType.ReadWrite<TransformFrame>(),
        ComponentType.Exclude<Deleted>(),
        ComponentType.Exclude<Temp>());
}

[Preserve]
protected override void OnUpdate()
{
    uint index = m_SimulationSystem.frameIndex % 16;
    m_HumanQuery.ResetFilter();
    m_HumanQuery.SetSharedComponentFilter(new UpdateFrame(index));

    // Build and schedule UpdateTransformDataJob (handles normal + stumbling movement)
    JobHandle netDependency;
    var searchTree = m_NetSearchSystem.GetNetSearchTree(readOnly: true, out netDependency);

    var job = new UpdateTransformDataJob {
        // assign component handles, lookups, and data like m_TerrainHeightData, m_NetSearchTree, m_TransformFrameIndex
    };

    JobHandle handle = JobChunkExtensions.ScheduleParallel(job, m_HumanQuery, JobHandle.CombineDependencies(base.Dependency, netDependency));
    m_TerrainSystem.AddCPUHeightReader(handle);
    m_NetSearchSystem.AddNetSearchTreeReader(handle);
    base.Dependency = handle;
}

Notes and tips for modders: - The heavy lifting is done in UpdateTransformDataJob: when modifying movement/animation logic, consider updating that job or wrapping/patching animation/velocity helpers. - The job uses many ComponentLookup/BufferLookup handles and expects them to be provided via the generated TypeHandle: when creating custom systems that interact with HumanMoveSystem, ensure you respect its scheduling and data access patterns to avoid race conditions. - Stumbling uses terrain and net geometry to find temporary ground supports; if modding net composition or prefab surface heights, these can affect stumbling/ground contact behavior. - The system coordinates read access with TerrainSystem and Game.Net.SearchSystem by registering job handles (AddCPUHeightReader / AddNetSearchTreeReader). If you schedule parallel readers of these data sources, make sure to register dependencies similarly.