Game.Serialization.LaneObjectSystem
Assembly: Assembly-CSharp (game assembly)
Namespace: Game.Serialization
Type: class
Base: GameSystemBase
Summary:
LaneObjectSystem is a managed ECS system responsible for collecting "lane objects" (vehicles, humans, animals, parked objects, blocked-lane markers, etc.) each frame and either adding them to per-lane buffers (LaneObject buffers) or inserting them into the global moving-object search tree. The system schedules a Burst-compiled IJobChunk (LaneObjectJob) that iterates archetype chunks containing any of the lane-related components and performs the following main tasks:
- For entities that have lane buffers for their current lanes, it adds a LaneObject entry to that lane's DynamicBuffer using NetUtils.AddLaneObject.
- For entities that do not belong to a lane buffer (for example flying aircraft or objects without a lane) it computes object bounds (using Transform + PrefabRef geometry data) and adds the entity to the moving search tree for spatial queries.
- Handles special cases for trailers, trains (front/rear positions), parked vehicles/trains, blocked lanes, and lane-change lanes.
The job is Burst-compiled and uses a moving search tree obtained from Game.Objects.SearchSystem. The system registers itself as a writer to the moving search tree so the tree is updated safely with the job's results.
Fields
-
private Game.Objects.SearchSystem m_ObjectSearchSystem
Holds a reference to the SearchSystem used to obtain the moving search tree that stores entities not attached to a lane buffer. -
private EntityQuery m_Query
EntityQuery used to select entities that contain any of the lane-related components (CarCurrentLane, CarTrailerLane, ParkedCar, ParkedTrain, WatercraftCurrentLane, AircraftCurrentLane, TrainCurrentLane, HumanCurrentLane, AnimalCurrentLane, BlockedLane). Required for update. -
private TypeHandle __TypeHandle
Container for the Component/Entity type handles used by the job. It contains read-only handles for the various current-lane components, buffer types and lookups, and provides an __AssignHandles(ref SystemState) helper used by OnCreateForCompiler(). -
private struct LaneObjectJob
(nested)
Burst-compiled IJobChunk implementation that performs the chunk-by-chunk processing described in the summary. See "Methods" and nested-type details below. -
private struct TypeHandle
(nested)
Generated helper struct that stores the EntityTypeHandle, ComponentTypeHandles and Buffer/Component lookups used by the job, and an __AssignHandles method to bind them to the system state.
Properties
- (none publicly exposed)
This system does not expose public properties. It uses internal/private fields and the ECS job pipeline to operate.
Constructors
public LaneObjectSystem()
Default constructor. System creation is managed by DOTS/ECS and the Game world; initialization occurs in OnCreate.
Methods
-
protected override void OnCreate()
Initializes m_ObjectSearchSystem (gets/creates Game.Objects.SearchSystem) and builds the EntityQuery that matches entities with any lane-related components. Calls RequireForUpdate(m_Query) so the system only runs when matching entities exist. -
protected override void OnUpdate()
Builds and schedules the Burst IJobChunk (LaneObjectJob) using the TypeHandle-based component & buffer handles and the moving search tree from m_ObjectSearchSystem.GetMovingSearchTree(...). Combines job dependencies, registers the job as a writer to the moving search tree (m_ObjectSearchSystem.AddMovingSearchTreeWriter(jobHandle)), and assigns base.Dependency to the scheduled job's JobHandle. -
protected override void OnCreateForCompiler()
Compiler-time helper used to bind type handles and assign queries when ECS generates code for the system. Calls __AssignQueries and __TypeHandle.__AssignHandles(ref base.CheckedStateRef). -
private void __AssignQueries(ref SystemState state)
Internal helper (generated) that ensures queries are assigned/created for the compiler; used by OnCreateForCompiler.
Nested: LaneObjectJob (Burst IJobChunk)
- Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
For each chunk it:
- Retrieves native arrays / buffers for the various lane-related components, Transform and PrefabRef.
- For each entity type (cars, trailers, parked cars, watercraft, aircraft, trains, humans, animals, blocked-lane buffer):
- If a lane buffer exists for the entity's lane, add an entry to that lane buffer via NetUtils.AddLaneObject (position varies: curve position, next position, front/rear pos for trains/parked trains, etc).
- Otherwise compute object bounds using Transform + PrefabRef -> ObjectGeometryData -> ObjectUtils.CalculateBounds, and insert the entity into the moving search tree (m_SearchTree.Add(entity, new QuadTreeBoundsXZ(bounds))).
- Trains and parked trains use TrainNavigationHelpers.GetCurvePositions to get front/rear curve positions and then add to the appropriate lane buffers if present.
- Blocked lanes are processed by iterating the BlockedLane buffer and adding entries to the corresponding lane buffers if available.
- The job uses:
- ComponentTypeHandle
Notes about thread-safety & performance:
- The job is Burst-compiled and runs as an IJobChunk for parallel chunkized execution.
- m_SearchTree is obtained from SearchSystem with readOnly:false and an out JobHandle dependency; the system registers the scheduled job as a writer so tree updates are safe.
- NetUtils.AddLaneObject writes to per-lane DynamicBuffers via BufferLookup
Usage Example
You do not normally call this system directly — it runs automatically when the EntityQuery matches. Example snippets that are useful for modders:
- Get the system instance (from a mod context) and check that it exists:
var world = World.DefaultGameObjectInjectionWorld;
var laneObjectSystem = world.GetExistingSystemManaged<Game.Serialization.LaneObjectSystem>();
if (laneObjectSystem != null) {
// system is present and will run each frame when there are matching entities
}
- Read lane objects for a specific lane entity (example: inspect the LaneObject buffer contents):
var em = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity laneEntity = /* obtain lane entity */;
if (em.HasBuffer<Net.LaneObject>(laneEntity)) {
var buffer = em.GetBuffer<Net.LaneObject>(laneEntity);
for (int i = 0; i < buffer.Length; i++) {
var laneObj = buffer[i];
// laneObj contains entity reference and curve position stored by NetUtils.AddLaneObject
}
}
- Notes for modders:
- If you add custom moving objects or customize Prefab/ObjectGeometryData, the system will either add them to lane buffers (if lanes are assigned) or to the moving search tree for spatial queries.
- Avoid mutating lane buffers or the moving search tree outside the system's job while it runs — instead use ECS patterns (commands, separate systems) to safely modify data.
- The job is Burst-compiled; keep user-managed managed calls out of components processed by this job.
If you want more concrete examples (e.g., how to add a custom entity with a CarCurrentLane so it appears in per-lane buffers, or how to query the moving search tree), tell me which scenario you need and I can add a short code sample.