Skip to content

Game.Serialization.ControllerSystem

Assembly: Assembly-CSharp (inferred)
Namespace: Game.Serialization

Type: class ControllerSystem

Base: GameSystemBase

Summary:
ControllerSystem is a Unity.Entities system that links "controller" entities to vehicle entities by reading a Buffer on controller entities. For each LayoutElement entry (which contains a reference to a vehicle Entity), the system checks whether the target vehicle has a Controller component; if it does, the system writes the controller Entity into Controller.m_Controller on the vehicle. The main work is performed inside a Burst-compiled IJobChunk (ControllerJob) and scheduled in OnUpdate. The system requires entities that have a LayoutElement buffer to run and uses ComponentLookup to perform safe concurrent reads/writes to Controller components.


Fields

  • private EntityQuery m_Query
    Query used to find entities that contain the LayoutElement buffer. The query is required for update via RequireForUpdate(m_Query) in OnCreate().

  • private TypeHandle __TypeHandle
    Holds the per-system type handles used for job scheduling:

  • EntityTypeHandle
  • BufferTypeHandle (read-only)
  • ComponentLookup (read/write) The TypeHandle has an __AssignHandles method that populates these handles from the SystemState.

  • private struct ControllerJob (nested struct)
    The Burst-compiled IJobChunk that iterates chunks of controller entities, reads their LayoutElement buffers, and updates Controller components on referenced vehicle entities.

  • private struct TypeHandle (nested struct)
    Container type used to store the value-type handles required by the job and to assign them from the SystemState.

Properties

  • None (no public properties are declared on ControllerSystem).

Constructors

  • public ControllerSystem()
    Default constructor. Marked with [Preserve] on the class and constructor to prevent Unity/linker stripping in build/IL2CPP scenarios.

Methods

  • protected override void OnCreate()
    Sets up the EntityQuery to select entities with Buffer and calls RequireForUpdate(m_Query) so the system only runs when matching entities exist.

  • protected override void OnUpdate()
    Builds and schedules the ControllerJob:

  • Obtains the EntityTypeHandle, BufferTypeHandle, and ComponentLookup via InternalCompilerInterface.Get* methods using the stored __TypeHandle and the system's CheckedStateRef.
  • Schedules the job against m_Query with JobChunkExtensions.Schedule and assigns the returned JobHandle to base.Dependency.

  • protected override void OnCreateForCompiler()
    Internal/compiler helper called by the generated code path. It calls __AssignQueries to initialize any queries and __TypeHandle.__AssignHandles to assign the internal handles from the SystemState.

  • private void __AssignQueries(ref SystemState state)
    Generated helper (called from OnCreateForCompiler) — here it creates and immediately disposes an EntityQueryBuilder(Allocator.Temp). In some generated systems this method is used to ensure query creation side-effects during compilation.

  • private struct TypeHandle.__AssignHandles(ref SystemState state)
    Assigns the concrete EntityTypeHandle, BufferTypeHandle (read-only), and ComponentLookup (read/write) from the provided SystemState. Marked with AggressiveInlining.

  • private struct ControllerJob.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Job execution logic:

  • Get the NativeArray of controller entities for the chunk.
  • Get the BufferAccessor for the chunk.
  • For each controller entity in the chunk:
    • Iterate its DynamicBuffer.
    • For each LayoutElement entry, get m_Vehicle (entity).
    • If that vehicle has a Controller component (m_ControllerData.HasComponent(vehicle)):
    • Read Controller value, set value.m_Controller = controller, and write it back (m_ControllerData[vehicle] = value).

Notes on concurrency and safety: - The job uses ComponentLookup to read/write Controller components on arbitrary vehicle entities. Ensure that no other job concurrently writes to the same components without proper dependencies. - The job is Burst compiled for performance.

Usage Example

// Example showing the result: after ControllerSystem runs, vehicles referenced
// from a controller entity's LayoutElement buffer will have their Controller.m_Controller
// field set to that controller entity.

[GenerateAuthoringComponent]
public struct Controller : IComponentData
{
    public Entity m_Controller; // will be written by ControllerSystem
}

public struct LayoutElement : IBufferElementData
{
    public Entity m_Vehicle; // vehicle entity reference
}

// No explicit registration is normally required: ControllerSystem is a GameSystemBase-derived
// system scheduled by the ECS world. You can observe the result like this:

public void Example_ReadController(EntityManager em, Entity vehicle)
{
    if (em.HasComponent<Controller>(vehicle))
    {
        Controller c = em.GetComponentData<Controller>(vehicle);
        Entity controllerEntity = c.m_Controller;
        // controllerEntity is the controller set by ControllerSystem (or Entity.Null)
    }
}

Additional notes: - The system relies on generated/internal helper calls (InternalCompilerInterface.Get*). This pattern is common for code produced by a source generator or compiler pipeline that emits optimized ECS code. - If adding new LayoutElement producers or Controller consumers, ensure the LayoutElement buffer is populated on controller entities so this system can establish the relationship.