Game.CarTrailerMoveSystem
Assembly: Assembly-CSharp (game)
Namespace: Game.Simulation
Type: public class (CompilerGenerated)
Base: GameSystemBase
Summary:
CarTrailerMoveSystem is an ECS system that updates trailer entities attached to tractor vehicles each simulation update. It schedules a Burst-compiled IJobChunk (CarTrailerMoveJob) that iterates vehicle archetype chunks matching a vehicle query, reads layout buffers (which define tractor + trailers chains), and computes trailer positions, rotations and velocities according to prefab data (CarData, CarTractorData, CarTrailerData) and the trailer's movement type (Free, Locked, or default). The system writes back Transform, Moving and TransformFrame buffer data for each trailer to keep interpolation and movement consistent over simulation frames. The job uses component lookups and buffer accessors and is scheduled in parallel for performance.
Fields
-
private SimulationSystem m_SimulationSystem
Holds a reference to the global SimulationSystem used to read simulation state such as frameIndex. Used to compute the transform frame index and timing values for interpolation. -
private EntityQuery m_VehicleQuery
An EntityQuery that targets vehicle entities: reads Car and LayoutElement and UpdateFrame, and excludes Stopped, Deleted and Temp. It is used to select which vehicle archetype chunks the CarTrailerMoveJob will run on. The query filter is reset every update and a shared component filter (UpdateFrame) is set for the current slice. -
private TypeHandle __TypeHandle
Compiler-generated container cached at runtime that stores EntityTypeHandle, ComponentTypeHandle, BufferTypeHandle and ComponentLookup handles required by the job. These are assigned via __AssignHandles(ref SystemState) before scheduling the job.
Properties
- This system exposes no public properties.
Constructors
public CarTrailerMoveSystem()
Default (preserved) constructor generated for this system; no special initialization beyond what GameSystemBase does.
Methods
-
protected override void OnCreate()
Initializes the system: obtains the SimulationSystem from the World and builds the m_VehicleQuery with the required component types and exclusions. This sets up the selection of vehicles that will be processed each update. -
protected override void OnUpdate()
Main scheduling method. It: - Computes an UpdateFrame index from the simulation frameIndex (
uint index = m_SimulationSystem.frameIndex & 0xF
) to select which vehicles to process this tick. - Resets and sets the shared component filter on m_VehicleQuery to process only the current UpdateFrame slice.
- Builds and schedules a parallel CarTrailerMoveJob (Burst compiled) using JobChunkExtensions.ScheduleParallel, passing in component type handles and lookups from __TypeHandle.
-
Computes m_TransformFrameIndex = m_SimulationSystem.frameIndex / 16 % 4 and passes it into the job. The job writes into a rotating buffer of TransformFrame entries for interpolation.
-
protected override void OnCreateForCompiler()
Called by compiler-generated initialization paths. It calls __AssignQueries and assigns type handles via __TypeHandle.__AssignHandles(ref base.CheckedStateRef). This supports the generated code paths for ECS. -
private void __AssignQueries(ref SystemState state)
Compiler helper; currently effectively empty (creates and disposes an EntityQueryBuilder). Present for compatibility with generated code. -
TypeHandle.__AssignHandles(ref SystemState state)
Assigns all EntityTypeHandle, ComponentTypeHandle, BufferTypeHandle and ComponentLookup fields from the provided SystemState. This prepares the type handles that the job uses when it is scheduled. -
CarTrailerMoveJob.Execute(in ArchetypeChunk chunk, ... )
This is the core job that runs per chunk. Key behavior: - Iterates entities in the chunk and reads their PrefabRef and LayoutElement dynamic buffer.
- For each layout element chain (index 1..N), treats element[0] as tractor and subsequent entries as trailer vehicles.
- If a chunk has the Unspawned component, trailer transforms are attached directly relative to the tractor (no complex movement).
- Otherwise, movement is computed based on CarTrailerData.m_MovementType:
- TrailerMovementType.Free: computes a look-direction from tractor attach point to trailer attach point, applies small velocity corrections (using local constant num = 4f/15f), normalizes, sets trailer rotation to face that direction and computes position relative to tractor attach and trailer attach offsets.
- TrailerMovementType.Locked: trailer rotation is locked to the tractor rotation; position is computed from tractor attach and trailer attach offsets.
- default: leaves trailer transform unchanged (uses trailer's current transform).
- Computes trailer velocity as displacement / num and produces a TransformFrame entry used for interpolation: position averaged between old and new, velocity set, rotation slerped halfway (math.slerp with t=0.5), flags copied from current transform frame.
- Writes updated Transform, Moving and the TransformFrame slot for the trailer entity.
- Chaining: if a layout has more than one trailer, after updating one trailer the job then uses the updated trailer as the "tractor" for the next trailer in chain (reads its CarTractorData) so multiple trailers follow sequentially.
Notes on implementation details: - Several ComponentLookup fields are marked with NativeDisableParallelForRestriction to allow concurrent read/write across chunks for fields like Transform and Moving. - The job uses prefab lookups (m_PrefabRefData, m_PrefabCarData, m_PrefabTractorData, m_PrefabTrailerData) to read prefab-specific offsets and movement type without having those components on the instance entity. - The job is Burst-compiled for performance.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
m_SimulationSystem = base.World.GetOrCreateSystemManaged<SimulationSystem>();
m_VehicleQuery = GetEntityQuery(
ComponentType.ReadOnly<Car>(),
ComponentType.ReadOnly<LayoutElement>(),
ComponentType.ReadOnly<UpdateFrame>(),
ComponentType.Exclude<Stopped>(),
ComponentType.Exclude<Deleted>(),
ComponentType.Exclude<Temp>());
}
Additional notes and modding tips: - Trailer prefab data: If you add or modify trailer/tractor prefabs, ensure CarTractorData.m_AttachPosition, CarTrailerData.m_AttachPosition, CarTrailerData.m_MovementType and CarData.m_PivotOffset are set correctly so this system calculates proper attachment offsets and movement. - Frame interpolation: The system writes into a rotating transform frame buffer indexed by m_TransformFrameIndex (computed from simulation frameIndex). If you change interpolation buffer sizes or timing, update the index arithmetic accordingly. - Concurrency & safety: ComponentLookup fields for Transform and Moving are used with NativeDisableParallelForRestriction to allow in-place writes; if you introduce other systems that modify the same components, ensure proper dependencies (JobHandle chaining) or schedule ordering. - Debugging: To debug behavior for an entity, you can temporarily disable BurstCompile on the job or add temporary logging (be mindful of performance). Observing the layout buffers (LayoutElement) is helpful to see chains of tractor/trailer relationships. - Performance: The job is scheduled in parallel on chunks. Avoid adding expensive per-entity managed operations inside this job; prefer prefab data reads and math operations as shown.