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 accessPoliceCarData
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 accessObjectData
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 accessMovingObjectData
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
orHelicopterData
-
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 requiresHelicopterData
; 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 intopurposeMask
. 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
byprobability
(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).