Game.Vehicles.ParkedVehiclesSystem
Assembly:
Namespace: Game.Vehicles
Type: public class ParkedVehiclesSystem
Base: GameSystemBase
Summary:
ParkedVehiclesSystem is a Unity DOTS-based game system responsible for managing parked vehicles associated with buildings and service facilities (police stations, fire stations, hospitals, transport depots, post facilities, maintenance depots, garbage facilities, etc.). The system:
- Finds valid parking/spawn locations around a building (parking lanes and spawn locations).
- Collects recently deleted vehicles so they can be re-used when respawning/duplicating.
- Duplicates parked vehicles when buildings are duplicated.
- Spawns parked service vehicles (police cars/helicopters, fire engines/helicopters, ambulances/hearses, transport vehicles, post vans, maintenance vehicles, garbage trucks) based on building data and upgrades.
- Uses a set of Burst-compiled IJob structs to perform expensive work in parallel and Native collections (NativeList, NativeParallelMultiHashMap) for temporary data.
- Interacts with owner/component lookups and uses EntityCommandBuffer (via a ModificationBarrier) to perform structural changes.
The system is tightly integrated with the game's prefab selection helpers (SelectData classes) and CityConfigurationSystem, and it only runs in game mode (see OnGamePreload).
Fields
-
private ModificationBarrier4B m_ModificationBarrier
Used to create command buffers for making structural changes (creating/removing entities, adding/removing components) from jobs. Jobs that produce EntityCommandBuffer are scheduled and the modification barrier tracks those producer handles. -
private CityConfigurationSystem m_CityConfigurationSystem
Reference to the city configuration system used by vehicle selection helpers to get configuration data (used in SelectData PreUpdate/PostUpdate patterns). -
private EntityQuery m_BuildingQuery
Query used to find buildings that need parked-vehicle handling (Updated + Building + OwnedVehicle and either Created or Temp, excluding some applied/upgrade cases). The system requires this query for update. -
private EntityQuery m_DeletedVehicleQuery
Query to collect deleted vehicle entities (Deleted + Vehicle + Temp) for potential reuse. -
private EntityQuery m_PoliceCarQuery
private EntityQuery m_FireEngineQuery
private EntityQuery m_HealthcareVehicleQuery
private EntityQuery m_TransportVehicleQuery
private EntityQuery m_PostVanQuery
private EntityQuery m_MaintenanceVehicleQuery
-
private EntityQuery m_GarbageTruckQuery
Queries used by the various SelectData classes to gather prefab pools / data required for selecting which vehicles to spawn. -
private PoliceCarSelectData m_PoliceCarSelectData
private FireEngineSelectData m_FireEngineSelectData
private HealthcareVehicleSelectData m_HealthcareVehicleSelectData
private TransportVehicleSelectData m_TransportVehicleSelectData
private PostVanSelectData m_PostVanSelectData
private MaintenanceVehicleSelectData m_MaintenanceVehicleSelectData
-
private GarbageTruckSelectData m_GarbageTruckSelectData
Selection helper objects used to choose prefab(s) for each service type and to create entities for them. These have PreUpdate/PostUpdate lifecycles. -
private TypeHandle __TypeHandle
Internal struct that caches EntityTypeHandle/ComponentLookup/BufferLookup/ComponentTypeHandle handles used by jobs and methods. Populated via __AssignHandles / OnCreateForCompiler. -
(Nested job types and temporaries) e.g.
FindParkingLocationsJob
,CollectDeletedVehiclesJob
,DuplicateVehiclesJob
,SpawnPoliceCarsJob
,SpawnFireEnginesJob
,SpawnHealthcareVehiclesJob
,SpawnTransportVehiclesJob
,SpawnPostVansJob
,SpawnMaintenanceVehiclesJob
,SpawnGarbageTrucksJob
, plus aParkingLocation
andDeletedVehicleData
struct.
Jobs are BurstCompiled and use ComponentLookup/BufferLookup/ComponentTypeHandles to read game data off the main thread.
Properties
- None (no public properties exposed)
Constructors
public ParkedVehiclesSystem()
Default constructor. The system initializes its fields in OnCreate rather than in the ctor. The system is annotated with [Preserve] for AOT/build-time safety.
Methods
-
protected override void OnCreate()
Initializes the system: fetches/creates the ModificationBarrier4B and CityConfigurationSystem, sets up EntityQuery objects used for buildings and vehicle selection, constructs the various SelectData helper objects and calls RequireForUpdate(m_BuildingQuery) so the system only runs when relevant building entities exist. -
protected override void OnGamePreload(Purpose purpose, GameMode mode)
Enables or disables the system depending on the game mode. Sets base.Enabled = mode.IsGame(). -
protected override void OnUpdate()
Main per-frame update. Iterates building archetype chunks from m_BuildingQuery, for each building: - Skips certain Temp flags.
- Spawns or duplicates vehicles based on building components and whether the building is a temporary/duplicate/delete operation.
- For each building, schedules jobs to find parking locations, collect deleted vehicles, duplicate vehicles, and schedule spawn jobs for each service type as required.
-
Manages job dependencies and ensures Native collections are disposed (or scheduled for disposal) properly. Important: OnUpdate orchestrates job scheduling and uses m_ModificationBarrier to get EntityCommandBuffer instances for producer jobs.
-
protected override void OnCreateForCompiler()
Helper called in compiled pipelines to assign queries and handles (__AssignQueries, __TypeHandle.__AssignHandles). Mostly internal boilerplate. -
private void FindParkingLocations(Entity entity, ref NativeList<ParkingLocation> parkingLocations, JobHandle inputDeps, ref JobHandle parkingLocationDeps)
Schedules FindParkingLocationsJob (if parkingLocations is not already created) which enumerates spawn locations (SpawnLocation elements and ParkingLane lanes) for the given building and fills a NativeListwith candidate parking locations. Uses ComponentLookup/BufferLookup to query curves, parking lanes, spawn locations and lane overlaps. -
private void CollectDeletedVehicles(ref NativeParallelMultiHashMap<Entity, DeletedVehicleData> deletedVehicleMap, JobHandle inputDeps, ref JobHandle deletedVehiclesDeps)
Schedules CollectDeletedVehiclesJob (once) which iterates all entities matching m_DeletedVehicleQuery and collects Deleted vehicles into a NativeParallelMultiHashMap keyed by primary prefab Entity. This allows later re-use of deleted vehicle entities instead of creating new ones. -
private void DuplicateVehicles(Entity entity, Temp temp, NativeList<ParkingLocation> parkingLocations, NativeParallelMultiHashMap<Entity, DeletedVehicleData> deletedVehicleMap, ref JobHandle parkingLocationDeps, ref JobHandle deletedVehiclesDeps)
Schedules DuplicateVehiclesJob which duplicates parked vehicles for building duplication operations. It uses OwnedVehicle buffers on the original building to recreate parked entities, reusing deleted vehicle entities when possible. Jobs write structural changes via m_ModificationBarrier.CreateCommandBuffer(). -
private void SpawnPoliceCars(Entity entity, Temp temp, bool isTemp, NativeList<ParkingLocation> parkingLocations, NativeParallelMultiHashMap<Entity, DeletedVehicleData> deletedVehicleMap, ref JobHandle parkingLocationDeps, ref JobHandle deletedVehiclesDeps)
private void SpawnFireEngines(Entity entity, Temp temp, bool isTemp, NativeList<ParkingLocation> parkingLocations, NativeParallelMultiHashMap<Entity, DeletedVehicleData> deletedVehicleMap, ref JobHandle parkingLocationDeps, ref JobHandle deletedVehiclesDeps)
private void SpawnHealthcareVehicles(...)
private void SpawnTransportVehicles(...)
private void SpawnPostVans(...)
private void SpawnMaintenanceVehicles(...)
private void SpawnGarbageTrucks(...)
Each of these schedules a corresponding Burst-compiled IJob (SpawnXJob) that:- Uses a Random instance seeded from building's PseudoRandomSeed component to pick prefabs (through SelectData).
- Uses UpgradeUtils to get combined building data (including installed upgrades).
- Selects suitable parking spaces using SelectParkingSpace (either deterministic or weighted/random selection), possibly reusing a deleted vehicle entity, or creating new entities via SelectData.CreateVehicle.
- Sets parked state components (ParkedCar/ParkedTrain) and other service-specific components (PoliceCar, FireEngine, Ambulance/Hearse, Taxi/PublicTransport/CargoTransport, PostVan, MaintenanceVehicle, GarbageTruck).
- Adds Owner and Temp/Animation/InterpolatedTransform when needed.
-
Writes structural changes via EntityCommandBuffer created from the modification barrier.
-
private static Entity GetSecondaryPrefab(Entity primaryPrefab, DynamicBuffer<LayoutElement> layoutElements, ref ComponentLookup<PrefabRef> prefabRefs, ref ComponentLookup<PrefabData> prefabDatas, out bool validLayout)
Inspect a layout buffer (LayoutElement) to find a secondary prefab (for multi-entity vehicles such as articulated buses). Returns the first different prefab found and sets validLayout depending on whether referenced secondary prefabs are enabled. -
private static float4 GetMaxVehicleSize(NativeList<ParkingLocation> locations, RoadTypes roadType)
Returns the maximum size (packed float4) available among the candidate parking locations for a given road type. -
private static bool SelectParkingSpace(ref Random random, NativeList<ParkingLocation> locations, ObjectGeometryData objectGeometryData, RoadTypes roadType, TrackTypes trackType, out Transform transform, out Entity lane, out float curvePosition)
Randomly selects a candidate parking location from a list, respecting size and road/track compatibility, uses VehicleUtils.CalculateParkingSpaceTarget for parking-lane spawn locations and adjusts curve position according to object offsets and slot angle. Removes the selected location from the list and returns true on success. -
private static Entity FindDeletedVehicle(Entity primaryPrefab, Entity secondaryPrefab, Transform transform, NativeParallelMultiHashMap<Entity, DeletedVehicleData> deletedMap)
Finds the nearest deleted vehicle (by primary & secondary prefab match) to a specified transform from the deleted vehicle map and removes that entry from the map, returning the entity if found. -
(Nested job structs)
FindParkingLocationsJob
— enumerates spawn location elements and parking lanes for a building and populates a NativeList. CollectDeletedVehiclesJob
— iterates deleted vehicle chunks and populates a NativeParallelMultiHashMap. DuplicateVehiclesJob
— duplicates parked vehicles when duplicating buildings (handles layout, controller relationships, ParkedCar/ParkedTrain, Temp/Hidden/BatchesUpdated, Owner).SpawnPoliceCarsJob
,SpawnFireEnginesJob
,SpawnHealthcareVehiclesJob
,SpawnTransportVehiclesJob
,SpawnPostVansJob
,SpawnMaintenanceVehiclesJob
,SpawnGarbageTrucksJob
— each selects vehicles and either reuses deleted entities or creates parked vehicle entities, sets service-specific components, and sets parked/owner/temp info.
Notes about concurrency and lifetime: - Native lists/maps used by jobs are allocated with Allocator.TempJob and disposed either on the main thread with scheduled disposal dependencies or by the job itself where appropriate. The OnUpdate method carefully combines and tracks JobHandle dependencies to dispose created collections safely. - The system uses m_ModificationBarrier to create EntityCommandBuffer instances that are passed into jobs (or .AsParallelWriter()) so that entity structural changes are correctly produced on worker threads and applied on the main thread by the barrier. - ComponentLookup / BufferLookup / ComponentTypeHandle instances are obtained from __TypeHandle to avoid creating handles repeatedly.
Usage Example
[Preserve]
protected override void OnCreate()
{
base.OnCreate();
// Get the modification barrier used to apply structural changes from jobs
m_ModificationBarrier = base.World.GetOrCreateSystemManaged<ModificationBarrier4B>();
// Obtain the city configuration system and create SelectData helpers
m_CityConfigurationSystem = base.World.GetOrCreateSystemManaged<CityConfigurationSystem>();
m_PoliceCarSelectData = new PoliceCarSelectData(this);
// ... initialize other SelectData instances and queries as done in the system
}
Additional tips for modders: - To change parked-vehicle spawning behavior, consider extending or replacing SelectData classes (e.g., PoliceCarSelectData) or intercepting the Spawn* jobs via a custom system that runs after ParkedVehiclesSystem (or disabling this system and providing your own). - When writing jobs that interact with this system's data structures, follow the same pattern for using EntityCommandBuffer via the modification barrier to avoid structural change race conditions. - Be careful with Native collections (NativeList, NativeParallelMultiHashMap) lifetime and job dependencies — leaking or prematurely disposing them will cause crashes.