Skip to content

Game.Simulation.CarMoveSystem

Assembly:
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
CarMoveSystem is an ECS system responsible for updating vehicle movement each frame. It gathers vehicles that need updating, prepares and schedules a highly-parallel Burst-compiled IJobChunk (CarMoveJob) to compute movement, orientation and lighting flags for each car, writes transform frames into per-vehicle buffers, and uses an EndFrameBarrier command buffer to enqueue component updates (e.g. Updated, EffectsUpdated, BatchesUpdated) when needed. The system reads lighting and terrain data, prefab car data and layout/sub-object buffers to update vehicles correctly (including terrain height sampling, light state randomness, reversing behavior, turn signals, and other flags). It also registers the job with the TerrainSystem as a CPU height reader and hands the job handle to the EndFrameBarrier so command buffer writes are correctly ordered.


Fields

  • private SimulationSystem m_SimulationSystem
    Reference to the global SimulationSystem used to read the frame index (and other simulation state) for deciding which vehicles to update this frame.

  • private TerrainSystem m_TerrainSystem
    Reference to the TerrainSystem used to acquire TerrainHeightData and to register the scheduled job as a CPU height reader.

  • private LightingSystem m_LightingSystem
    Reference to the LightingSystem used to read dayLightBrightness (used to set vehicle lights).

  • private EndFrameBarrier m_EndFrameBarrier
    Barrier system used to create a parallel EntityCommandBuffer for enqueuing structural changes (e.g. adding Updated/EffectsUpdated/BatchesUpdated components) from the job.

  • private EntityQuery m_VehicleQuery
    Query used to select vehicles to update. The query filters for entities with Car and UpdateFrame, and excludes Deleted, Temp, TripSource and OutOfControl.

  • private TypeHandle __TypeHandle
    Internal container for all Entity/Component/Buffer/Lookup handles used by the scheduled job. Assigned in OnCreateForCompiler.

Properties

  • None (no public properties exposed by this system)

Constructors

  • public CarMoveSystem()
    Default constructor. System initialization is performed by the framework and OnCreate / OnCreateForCompiler.

Methods

  • protected override void OnCreate()
    Initializes the system: grabs references to SimulationSystem, TerrainSystem, LightingSystem and EndFrameBarrier from the World and constructs the vehicle EntityQuery used during updates.

  • protected override void OnUpdate()
    Main update method. It:

  • Computes frame-based indices (update frame index and transform-frame index) from SimulationSystem.frameIndex.
  • Filters m_VehicleQuery by UpdateFrame (shared component) so only vehicles scheduled for this sub-frame are processed.
  • Constructs and schedules CarMoveJob (Burst compiled) in parallel across matching archetype chunks, providing component/type handles, lookups, lighting/terrain data and an EntityCommandBuffer.ParallelWriter from EndFrameBarrier.
  • Registers the job as a CPU height reader with TerrainSystem and passes the job handle to EndFrameBarrier to ensure command buffer execution ordering.
  • Sets the system's dependency to the scheduled job handle.

  • protected override void OnCreateForCompiler()
    Called by the generated/compiled runtime path to assign handles and queries required by jobs. Internally calls __AssignQueries and assigns handles in __TypeHandle.

  • private void __AssignQueries(ref SystemState state)
    Internal helper used by the compiler-generated setup. In this compiled version the method creates (and disposes) an EntityQueryBuilder placeholder — its presence ensures compatibility with compiled pipeline.

Nested types (summary):

  • private struct CarMoveJob : IJobChunk (BurstCompile)
    The core chunk job that iterates vehicle archetype chunks and for each entity:
  • Reads Car, CarNavigation, CarCurrentLane, PrefabRef, PseudoRandomSeed, and other read-only data.
  • Reads/writes Moving and Transform components and writes a TransformFrame into the entity buffer at the current transform frame index.
  • Computes movement direction/velocity, handles reversing/turning/area-based movement, applies terrain height sampling for area lanes, normalizes and clamps velocities, and updates orientation using LookRotation logic.
  • Determines per-frame TransformFlags (main/extralights, braking, reversing, turn signals, warning/work/interior lights) using lighting brightness and random seed.
  • Uses an EntityCommandBuffer.ParallelWriter to add components to entities (Updated, EffectsUpdated, BatchesUpdated) when visual/effect state changes require a full update. It also traverses sub-objects (via SubObject buffer) to propagate BatchesUpdated additions recursively.
  • Contains helper methods: EffectsUpdated, ForceFullUpdate, UpdateVehicle, UpdateSubObjectBatches which add command-buffered component updates for vehicle/sub-objects and their batches.

Important job parameters include: - m_TransformFrameIndex: current write index into TransformFrame ring buffer (computed from simulation frame index). - m_DayLightBrightness and Random seed: used to determine headlights/extra lights. - m_TerrainHeightData: used for terrain-aligned movement in area lanes. - m_CommandBuffer: EntityCommandBuffer.ParallelWriter from EndFrameBarrier used to enqueue structural changes safely from job threads.

  • private struct TypeHandle
    Holds the various Entity/Component/Buffer type handles and lookups used by CarMoveJob. Provides __AssignHandles(ref SystemState) to populate handles from the SystemState.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
    m_TerrainSystem = base.World.GetOrCreateSystemManaged<TerrainSystem>();
    m_LightingSystem = base.World.GetOrCreateSystemManaged<LightingSystem>();
    m_EndFrameBarrier = base.World.GetOrCreateSystemManaged<EndFrameBarrier>();
    m_VehicleQuery = GetEntityQuery(
        ComponentType.ReadOnly<Car>(),
        ComponentType.ReadOnly<UpdateFrame>(),
        ComponentType.ReadWrite<TransformFrame>(),
        ComponentType.Exclude<Deleted>(),
        ComponentType.Exclude<Temp>(),
        ComponentType.Exclude<TripSource>(),
        ComponentType.Exclude<OutOfControl>()
    );
}

Notes and tips for modders: - The system selects which vehicles to run by using a shared UpdateFrame(index) component. To manually include/exclude a vehicle from a given sub-frame, adjust that shared component. - CarMoveJob writes to a TransformFrame circular buffer index computed from SimulationSystem.frameIndex; ensure any code reading transform frames uses the same indexing scheme. - EffectsUpdated / Updated / BatchesUpdated are added via an EndFrameBarrier command buffer. If you depend on those components being present in the same frame as CarMoveSystem runs, consider the EndFrameBarrier ordering. - Terrain height is read via TerrainSystem.GetHeightData() and the job registers itself as a CPU height reader — if you change terrain data access patterns, ensure proper synchronization with TerrainSystem.