Skip to content

Game.Prefabs.PoliceCarSelectData

Assembly: Assembly-CSharp (game)
Namespace: Game.Prefabs

Type: struct

Base: System.ValueType

Summary:
Helper value-type used by game systems to locate, filter and instantiate police vehicle prefabs (cars and helicopters). It caches matching prefab archetype chunks, keeps component handles and requirement-checking state, and exposes methods to select a random suitable police vehicle given a purpose and road type and to create vehicle entities (parked or unparked) through an EntityCommandBuffer. PreUpdate/PostUpdate manage the lifecycle of the cached chunk list and required handle updates.


Fields

  • private NativeList<ArchetypeChunk> m_PrefabChunks
    Holds the list of archetype chunks matching the prefab query returned by GetEntityQueryDesc. Filled in PreUpdate via query.ToArchetypeChunkListAsync and disposed in PostUpdate. The list is allocated with the provided Allocator and its disposal is scheduled with the JobHandle returned by ToArchetypeChunkListAsync.

  • private VehicleSelectRequirementData m_RequirementData
    Auxiliary helper used to evaluate additional, configurable spawning requirements per prefab/chunk (e.g., config-driven restrictions), queried/updated each PreUpdate to reflect current city configuration and other dynamic requirements.

  • private EntityTypeHandle m_EntityType
    Component/variable handle used to read entity IDs out of ArchetypeChunk NativeArrays. Updated each PreUpdate (calls Update on the handle).

  • private ComponentTypeHandle<PoliceCarData> m_PoliceCarType
    Read-only component handle to access PoliceCarData per entity in a chunk. Updated each PreUpdate.

  • private ComponentTypeHandle<CarData> m_CarType
    Read-only component handle to detect car-type prefabs inside chunks. Used to filter chunk contents when road type is Car. Updated each PreUpdate.

  • private ComponentTypeHandle<HelicopterData> m_HelicopterType
    Read-only component handle to detect helicopter-type prefabs inside chunks. Used to filter chunk contents when road type is Helicopter. Updated each PreUpdate.

  • private ComponentLookup<ObjectData> m_ObjectData
    Lookup to access ObjectData on prefab entities (for example to fetch the base archetype used when spawning non-parked/active entities). Updated each PreUpdate and used by GetArchetype.

  • private ComponentLookup<MovingObjectData> m_MovingObjectData
    Lookup to access MovingObjectData on prefab entities (for example to fetch stopped/parked archetype). Updated each PreUpdate and used by GetArchetype when creating parked vehicles.

Properties

  • This struct exposes no public properties.

Constructors

  • public PoliceCarSelectData(SystemBase system)
    Initializes the selection helper: creates/initializes the VehicleSelectRequirementData and captures component/lookup handles (EntityTypeHandle, ComponentTypeHandle for PoliceCarData/CarData/HelicopterData, ComponentLookup for ObjectData and MovingObjectData). The NativeList of chunks is left default and actually populated in PreUpdate.

Methods

  • public static EntityQueryDesc GetEntityQueryDesc()
    Returns an EntityQueryDesc suitable for finding police vehicle prefabs:
  • All: PoliceCarData, ObjectData, PrefabData
  • Any: CarData or HelicopterData
  • None: Locked This query is intended to find all unlocked police vehicle prefabs (cars and helicopters) and their object/prefab metadata.

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

  • Calls query.ToArchetypeChunkListAsync(allocator, out jobHandle) to obtain the current prefab chunks that match the query. This is asynchronous and returns a JobHandle.
  • Updates the VehicleSelectRequirementData and all component/lookup handles with the given system. Parameters:
  • system: the SystemBase driving updates (used to Update handles).
  • cityConfigurationSystem: passed to m_RequirementData.Update for dynamic requirement data.
  • query: the EntityQuery produced from GetEntityQueryDesc.
  • allocator: allocator used to create the NativeList of chunks.
  • out jobHandle: asynchronous job handle that must be observed (e.g., completed before reading chunks on the main thread).

  • public void PostUpdate(JobHandle jobHandle)
    Disposes the NativeList of archetype chunks. Disposal is scheduled with the provided JobHandle to ensure the list is not disposed while async jobs still reference it.

  • public Entity SelectVehicle(ref Random random, ref PolicePurpose purposeMask, RoadTypes roadType)
    Convenience wrapper that calls the internal GetRandomVehicle to pick a prefab Entity matching the provided purpose mask and road type. The purposeMask is updated to the selected vehicle's purpose mask (so callers can know the exact purpose used).

  • public Entity CreateVehicle(EntityCommandBuffer commandBuffer, ref Random random, Transform transform, Entity source, Entity prefab, ref PolicePurpose purposeMask, RoadTypes roadType, bool parked)
    Creates a vehicle entity immediately via a non-parallel EntityCommandBuffer:

  • If prefab == Entity.Null, selects a random vehicle matching the purpose and road type.
  • Creates an entity using the archetype determined by GetArchetype(prefab, parked).
  • Sets Transform, PrefabRef(prefab), and PseudoRandomSeed generated from the provided Random.
  • If not parked: adds TripSource(source) and Unspawned components. Returns the created entity or Entity.Null if no suitable prefab could be found.

  • public Entity CreateVehicle(EntityCommandBuffer.ParallelWriter commandBuffer, int jobIndex, ref Random random, Transform transform, Entity source, Entity prefab, ref PolicePurpose purposeMask, RoadTypes roadType, bool parked)
    Same as above but for use inside a parallel job with an EntityCommandBuffer.ParallelWriter. The jobIndex is used for buffered operations.

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

  • If parked: returns the prefab's stopped archetype from m_MovingObjectData[prefab].m_StoppedArchetype.
  • Otherwise: returns the prefab's active archetype from m_ObjectData[prefab].m_Archetype.

  • private Entity GetRandomVehicle(ref Random random, ref PolicePurpose purposeMask, RoadTypes roadType)
    Core selection routine:

  • Iterates the cached m_PrefabChunks.
  • Filters chunks by roadType: for Car requires CarData, for Helicopter requires HelicopterData; otherwise skips.
  • For each entity in a matching chunk:
    • Checks whether (policeCarData.m_PurposeMask & purposeMask) != 0 (vehicle supports requested purpose).
    • Checks m_RequirementData.CheckRequirements for the chunk + index.
    • Uses PickVehicle with a fixed per-candidate probability (100) and cumulative totalProbability to perform weighted/random selection across all candidates.
  • If a vehicle is selected, sets result Entity and updates policePurpose to that vehicle's purpose mask; at end writes selected purpose mask back into purposeMask. Returns selected prefab Entity or Entity.Null if none matched.

  • private bool PickVehicle(ref Random random, int probability, ref int totalProbability)
    Random selection helper implementing a cumulative-probability selection approach:

  • Increments totalProbability by probability (in this code probability is 100 for each candidate).
  • Returns true if random.NextInt(totalProbability) < probability. Used to fairly pick one candidate among many without storing all candidates first (effectively does weighted random selection in a single pass).

Usage Example

// Example usage within a SystemBase:
// - Create PoliceCarSelectData in OnCreate.
// - Each update call PreUpdate to build the prefab chunk list, complete the returned JobHandle
//   before reading/selecting, use CreateVehicle to spawn, then call PostUpdate to dispose.

private PoliceCarSelectData m_PoliceSelect;
private EntityQuery m_PolicePrefabQuery;
private CityConfigurationSystem m_CityConfig;

protected override void OnCreate()
{
    base.OnCreate();
    m_PoliceSelect = new PoliceCarSelectData(this);
    m_PolicePrefabQuery = GetEntityQuery(PoliceCarSelectData.GetEntityQueryDesc());
    m_CityConfig = World.GetExistingSystem<CityConfigurationSystem>();
}

protected override void OnUpdate()
{
    JobHandle jobHandle;
    m_PoliceSelect.PreUpdate(this, m_CityConfig, m_PolicePrefabQuery, Allocator.TempJob, out jobHandle);

    // Ensure the asynchronous chunk list has been populated before reading it on main thread:
    jobHandle.Complete();

    // Example selection and spawn
    Random rnd = new Random((uint)UnityEngine.Random.Range(1, int.MaxValue));
    PolicePurpose purposeMask = PolicePurpose.Patrol; // example enum value
    RoadTypes roadType = RoadTypes.Car;

    // Select a prefab (could be Entity.Null)
    Entity prefab = m_PoliceSelect.SelectVehicle(ref rnd, ref purposeMask, roadType);
    if (prefab != Entity.Null)
    {
        var ecb = new EntityCommandBuffer(Allocator.Temp);
        Transform spawnTransform = new Transform { /* set position/rotation/scale as needed */ };

        // Create an unparked vehicle using the command buffer
        Entity created = m_PoliceSelect.CreateVehicle(ecb, ref rnd, spawnTransform, Entity.Null, prefab, ref purposeMask, roadType, parked: false);

        // playback commands to the world
        ecb.Playback(EntityManager);
        ecb.Dispose();
    }

    // Dispose cached chunk list (schedules with jobHandle)
    m_PoliceSelect.PostUpdate(jobHandle);
}

Notes: - The Random used is Unity.Mathematics.Random and must be passed by ref.
- PreUpdate returns a JobHandle from the asynchronous chunk list creation; ensure the job is complete before accessing the chunk contents on the main thread or otherwise coordinate correctly with jobs. PostUpdate disposes the NativeList and should be called exactly once after PreUpdate.
- The struct is designed to be a lightweight value object held by a system; do not leak the internal NativeList (it is created/disposed each frame).