Skip to content

Game.Prefabs.MaintenanceVehicleSelectData

Assembly: Assembly-CSharp.dll
Namespace: Game.Prefabs

Type: struct

Base: System.ValueType

Summary:
Helper struct used by simulation systems to select and spawn maintenance vehicles (garbage trucks, snowplows, etc.). It queries prefab archetype chunks that contain MaintenanceVehicleData and related components, filters them by maintenance types, parking-size constraints and other requirements, and can create vehicle entities (parked or active). Designed to be used from a SystemBase: call PreUpdate before scheduling jobs that will read the prefab chunks, and call PostUpdate after the async query completes to dispose resources. It integrates with VehicleSelectRequirementData to apply additional per-prefab requirements.


Fields

  • private NativeList<ArchetypeChunk> m_PrefabChunks
    Holds the archetype chunks returned by the entity query (prefabs matching the static GetEntityQueryDesc). Obtained via ToArchetypeChunkListAsync in PreUpdate and must be disposed in PostUpdate.

  • private VehicleSelectRequirementData m_RequirementData
    Helper that evaluates additional selection requirements (e.g., DLC/availability/other custom checks) on a per-chunk/per-index basis.

  • private EntityTypeHandle m_EntityType
    Entity type handle used to read Entity IDs from archetype chunks. Updated in PreUpdate via GetEntityTypeHandle().

  • private ComponentTypeHandle<MaintenanceVehicleData> m_MaintenanceVehicleType
    ComponentTypeHandle for reading MaintenanceVehicleData from prefab chunks. Updated in PreUpdate.

  • private ComponentTypeHandle<ObjectGeometryData> m_ObjectGeometryDataType
    ComponentTypeHandle for reading geometry/parking size information from prefabs. Updated in PreUpdate.

  • private ComponentLookup<ObjectData> m_ObjectData
    ComponentLookup used to access ObjectData on prefab entities (contains the vehicle archetype, etc.). Updated in PreUpdate.

  • private ComponentLookup<MovingObjectData> m_MovingObjectData
    ComponentLookup used to access MovingObjectData on prefab entities (contains stopped/parked archetype, etc.). Updated in PreUpdate.

Properties

  • (none)

Constructors

  • public MaintenanceVehicleSelectData(SystemBase system)
    Initializes the select helper. Prepares internal requirement helper and obtains initial ComponentTypeHandle/ComponentLookup instances from the provided SystemBase. Does not run the entity query — call PreUpdate to populate m_PrefabChunks.

Parameters: - system: the SystemBase instance (typically the system that owns this helper). Used to obtain type handles/lookups and to initialize VehicleSelectRequirementData.

Methods

  • public static EntityQueryDesc GetEntityQueryDesc()
    Returns an EntityQueryDesc that matches maintenance vehicle prefabs. The query requires:
  • MaintenanceVehicleData (read-only)
  • CarData (read-only)
  • ObjectData (read-only)
  • PrefabData (read-only) and excludes Locked (read-only). Use this query with EntityManager/SystemBase to build an EntityQuery and pass it into PreUpdate.

  • public void PreUpdate(SystemBase system, CityConfigurationSystem cityConfigurationSystem, EntityQuery query, Allocator allocator, out JobHandle jobHandle)
    Populates internal state before selection/spawning:

  • Calls query.ToArchetypeChunkListAsync(allocator, out jobHandle) to get prefab chunks asynchronously and assigns to m_PrefabChunks.
  • Updates VehicleSelectRequirementData and all type/lookup handles (m_EntityType, m_MaintenanceVehicleType, m_ObjectGeometryDataType, m_ObjectData, m_MovingObjectData). Notes:
  • jobHandle is the handle for the async ToArchetypeChunkListAsync call. You must ensure jobHandle completes (via PostUpdate disposal or by combining it with other handles) before accessing m_PrefabChunks on the main thread.

  • public void PostUpdate(JobHandle jobHandle)
    Disposes the m_PrefabChunks NativeList by calling Dispose(jobHandle). Call this after any jobs that depend on m_PrefabChunks are complete. Ensures safe disposal of the async list.

  • public Entity SelectVehicle(ref Random random, MaintenanceType allMaintenanceTypes, MaintenanceType anyMaintenanceTypes, float4 maxParkingSizes)
    Convenience wrapper that returns an Entity representing a matching prefab chosen by GetRandomVehicle. Returns Entity.Null if none match.

Parameters: - random: pseudo-random generator (passed by ref). - allMaintenanceTypes: bitmask of maintenance types that must all be present on the vehicle. - anyMaintenanceTypes: bitmask of maintenance types where at least one bit must match (if not None). - maxParkingSizes: maximum allowed parking size (float4 packing) used to filter prefabs that are too large.

  • public Entity CreateVehicle(EntityCommandBuffer commandBuffer, ref Random random, Transform transform, Entity source, Entity prefab, MaintenanceType allMaintenanceTypes, MaintenanceType anyMaintenanceTypes, float4 maxParkingSizes, bool parked)
    Creates a vehicle entity immediately into the given EntityCommandBuffer (main-thread ECB):
  • If prefab == Entity.Null, selects a prefab with GetRandomVehicle first.
  • Creates an entity with the correct archetype (parked => stopped archetype, otherwise regular object archetype).
  • Sets Transform, PrefabRef, and PseudoRandomSeed.
  • If not parked, adds TripSource(source) and Unspawned components. Returns the created Entity or Entity.Null if no suitable prefab was found.

  • public Entity CreateVehicle(EntityCommandBuffer.ParallelWriter commandBuffer, int jobIndex, ref Random random, Transform transform, Entity source, Entity prefab, MaintenanceType allMaintenanceTypes, MaintenanceType anyMaintenanceTypes, float4 maxParkingSizes, bool parked)
    Same as above but uses a parallel ECB writer for use inside jobs. jobIndex is required by the ParallelWriter to schedule writes safely.

  • private EntityArchetype GetArchetype(Entity prefab, bool parked)
    Returns the EntityArchetype to use when creating the vehicle:

  • If parked: returns m_MovingObjectData[prefab].m_StoppedArchetype (parked/stopped archetype).
  • Otherwise: returns m_ObjectData[prefab].m_Archetype (regular spawning archetype).

  • private Entity GetRandomVehicle(ref Random random, MaintenanceType allMaintenanceTypes, MaintenanceType anyMaintenanceTypes, float4 maxParkingSizes)
    Iterates over m_PrefabChunks and filters candidate prefabs:

  • Filters by maintenance type (must include all bits in allMaintenanceTypes, and if anyMaintenanceTypes != None must match at least one bit).
  • Uses VehicleSelectRequirementData.CheckRequirements to apply additional per-prefab conditions.
  • Uses ObjectGeometryData (via VehicleUtils.GetParkingSize) and maxParkingSizes to exclude prefabs whose parking footprint exceeds allowed size.
  • Chooses prefabs that minimize the bit-difference between vehicle maintenance types and allMaintenanceTypes (fewer missing bits preferred). Among equally-good candidates it uses a uniform random selection implemented by PickVehicle (accumulating probability to ensure equal chance across N matching entries). Returns the selected prefab Entity or Entity.Null if none match.

  • private bool PickVehicle(ref Random random, int probability, ref int totalProbability)
    Simple incremental selection helper implementing uniform selection among candidates:

  • Adds probability to totalProbability and returns true if random.NextInt(totalProbability) < probability.
  • Used by GetRandomVehicle with constant probability (100) so that each candidate has equal chance among those considered.

Usage Example

public partial class MaintenanceSpawnerSystem : SystemBase
{
    private MaintenanceVehicleSelectData m_SelectData;
    private EntityQuery m_VehiclePrefabQuery;

    protected override void OnCreate()
    {
        base.OnCreate();
        m_SelectData = new MaintenanceVehicleSelectData(this);
        m_VehiclePrefabQuery = GetEntityQuery(MaintenanceVehicleSelectData.GetEntityQueryDesc());
    }

    protected override void OnUpdate()
    {
        // Prepare the select data and get async prefab chunks
        JobHandle prefabJobHandle;
        m_SelectData.PreUpdate(this, World.GetExistingSystem<CityConfigurationSystem>(), m_VehiclePrefabQuery, Allocator.TempJob, out prefabJobHandle);

        // ... schedule jobs that might read the prefab chunks (if any). Make sure to use prefabJobHandle.

        // When done with jobs that rely on the async list:
        m_SelectData.PostUpdate(prefabJobHandle);

        // Example: spawn a vehicle immediately on the main thread
        var rand = new Random(1234);
        float4 maxParking = new float4(2, 2, 0, 0);
        Entity prefab = m_SelectData.SelectVehicle(ref rand, MaintenanceType.Garbage, MaintenanceType.None, maxParking);
        if (prefab != Entity.Null)
        {
            var ecb = new EntityCommandBuffer(Allocator.Temp);
            m_SelectData.CreateVehicle(ecb, ref rand, new Transform { /* ... */ }, Entity.Null, prefab, MaintenanceType.Garbage, MaintenanceType.None, maxParking, parked: false);
            ecb.Playback(EntityManager);
            ecb.Dispose();
        }
    }
}

Notes and tips: - Always call PreUpdate before using the select helper and ensure PostUpdate is called to dispose the NativeList created by ToArchetypeChunkListAsync. Failing to dispose it will leak native memory. - The struct expects component handles/lookups to be updated each frame via PreUpdate so it is safe to call multiple times per frame as long as you follow the PreUpdate/PostUpdate lifecycle. - Use the GetEntityQueryDesc() provided to build the EntityQuery passed to PreUpdate — that query selects the prefab set the selector is designed to evaluate.