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.