Skip to content

Game.VehicleOutOfControlSystem

Assembly: Game (inferred)
Namespace: Game.Simulation

Type: class

Base: GameSystemBase

Summary:
VehicleOutOfControlSystem handles the simulation and physics updates for vehicles flagged as OutOfControl. It schedules a Burst-compiled IJobChunk (VehicleOutOfControlMoveJob) that integrates vehicle translational and angular velocities over multiple sub-steps, samples terrain and nearby network geometry to determine ground contact heights, applies grip/braking forces at corner/sample points, damps velocities, updates Transform and Moving components, and writes a TransformFrame into the vehicle's buffer for interpolation/visualization. The system obtains TerrainHeightData and a NetSearchTree for collision/ground queries and filters entities by an UpdateFrame shared component so it only executes for the current simulation slices. It is optimized for multithreaded execution with Unity Jobs + Burst and uses ComponentLookup and ComponentTypeHandle accessors for ECS data.


Fields

  • private SimulationSystem m_SimulationSystem
    Initializes and provides the current simulation frame index and scheduling context. Used to compute TransformFrame index and to obtain the frame index for shared-component filtering.

  • private TerrainSystem m_TerrainSystem
    Provides TerrainHeightData and registers job readers so terrain height data is not modified concurrently while the job runs.

  • private Game.Net.SearchSystem m_NetSearchSystem
    Provides the NativeQuadTree used to query nearby network nodes/edges for more precise ground-contact heights (e.g., road surfaces, nodes).

  • private EntityQuery m_VehicleQuery
    EntityQuery used to select vehicles that have the OutOfControl and UpdateFrame components and the necessary read/write components (Transform, Moving, TransformFrame). The query excludes Deleted, Temp and TripSource entities and is required for update.

  • private TypeHandle __TypeHandle
    Holds ComponentTypeHandle / BufferTypeHandle and ComponentLookup instances used to access ECS component arrays in the job. It includes a method to assign handles from a SystemState.

Properties

  • None
    This system does not expose public properties.

Constructors

  • public VehicleOutOfControlSystem()
    Default constructor annotated with [Preserve]. The system uses OnCreate to initialize references to other systems and to build its EntityQuery.

Methods

  • protected override void OnCreate()
    Sets up references to required systems (SimulationSystem, TerrainSystem, Game.Net.SearchSystem) and constructs the EntityQuery (m_VehicleQuery) used to select out-of-control vehicles. Also calls RequireForUpdate(m_VehicleQuery) so the system only runs when matching entities exist.

  • protected override void OnUpdate()
    Main scheduling entry point. Computes the current TransformFrame index from the simulation frame index, applies a shared-component filter (UpdateFrame) to m_VehicleQuery, constructs and schedules the VehicleOutOfControlMoveJob via JobChunkExtensions.ScheduleParallel, providing:

  • ComponentTypeHandle and BufferTypeHandle via InternalCompilerInterface and __TypeHandle
  • ComponentLookup accessors for various net/prefab geometry components
  • TerrainHeightData from TerrainSystem
  • A read-only NativeQuadTree from the NetSearchSystem (with a job dependency returned)
  • The transform frame index to write into the vehicle's TransformFrame buffer

After scheduling the job it registers the jobHandle with TerrainSystem (AddCPUHeightReader) and NetSearchSystem (AddNetSearchTreeReader) to declare read access and sets base.Dependency to the scheduled job handle.

  • protected override void OnCreateForCompiler()
    Compiler helper used in generated/stripped builds to assign query and type handles. Calls __AssignQueries and __TypeHandle.__AssignHandles.

  • private void __AssignQueries(ref SystemState state)
    Internal helper that (in the provided compiled form) ensures query-related initialization; here it's a no-op that disposes an empty EntityQueryBuilder; included for compatibility with generated code.

  • private struct TypeHandle.__AssignHandles(ref SystemState state)
    Assigns ComponentTypeHandle and ComponentLookup instances from the SystemState. Called from OnCreateForCompiler to initialize the TypeHandle before job scheduling.

  • Nested: private struct VehicleOutOfControlMoveJob : IJobChunk

  • Burst-compiled job that processes chunks of vehicles in parallel. For each entity it:
    • Reads PrefabRef to get CarData and ObjectGeometryData (object size / bounds).
    • Iterates several internal sub-steps (num = 4 sub-steps) each of which:
    • Computes moment of inertia, forward vector, pivot/origin offset, base and corner quads for the vehicle.
    • Calls GetGroundHeight to sample terrain + net geometry and obtain per-corner ground heights.
    • Computes per-corner linear velocity deltas (CalculatePointVelocityDelta overloads) factoring grip/braking, vertical free-fall and ground penetration corrections, and clamps lateral deltas based on grip.
    • Computes per-corner angular velocity deltas (CalculatePointAngularVelocityDelta).
    • Integrates angular velocity into rotation (using quaternion axis-angle) and corrects position to keep pivot consistent.
    • Integrates translational velocity and applies damping (exponential decay with time step).
    • Writes a TransformFrame entry into the vehicle's TransformFrame DynamicBuffer at the computed frame index (m_TransformFrameIndex), and writes back updated Moving and Transform components.
  • The job also contains a nested NetIterator that implements INativeQuadTreeIterator to query nearby net entities and compute more accurate ground heights by intersecting triangles/segments and circles from network geometry and returning the maximum ground height under each sampled corner point, but ignoring surfaces further than 4 units above the corner sample (threshold in checks).

Important helper methods inside the job: - GetGroundHeight(...) — samples terrain heights at corner points, initializes heights to float.MinValue where not relevant, sets up NetIterator with a bounding box expanded by the vehicle's vertical motion for the sub-step, and iterates over the NetSearchTree to refine heights using network geometry. - CalculatePointVelocityDelta(...) — two overloads that compute linear velocity impulse to apply at a sampled point based on local point velocity, forward vector (or half-leverage), grip/braking, gravity/time-step, and penetration into ground; returns a small corrective linear delta applied to Moving.m_Velocity. - CalculatePointAngularVelocityDelta(...) — converts a per-point linear delta into angular velocity delta using cross product with the lever arm and dividing by moment-of-inertia. - Execute(in ArchetypeChunk chunk, ...) — chunk loop that iterates chunk.Count items and performs the per-entity logic described above.

NetIterator details: - Iterates net elements in the quad-tree whose bounds intersect the vehicle's swept bounds. - For node/orphan entities, checks circle intersection using prefab composition width and updates ground heights. - For edge entities, subdivides segments/turn geometry (including special-handling of middleRadius) into smaller segments and checks triangle intersections with vehicle sample points. - Uses MathUtils.Intersect and triangle xz intersection to determine if network triangles or circles lie under vehicle sample points and uses triangle positions to update ground height candidates.

  • void IJobChunk.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
    Explicit interface implementation calling the strong-typed Execute method.

Usage Example

[Preserve]
protected override void OnCreate()
{
    base.OnCreate();
    // VehicleOutOfControlSystem config is set up automatically:
    // - Queries created to select OutOfControl vehicles
    // - References to SimulationSystem, TerrainSystem, NetSearchSystem are acquired
    // The system will then run OnUpdate() and schedule the VehicleOutOfControlMoveJob
    // for all matching entities each simulation tick when present.
}

Notes and modding tips: - The system uses a shared-component filter UpdateFrame(index) so OutOfControl vehicles are processed only on their assigned update slice. When testing, ensure the UpdateFrame for the entity matches the simulation system's frame index slice. - All heavy computation is in a Burst-compiled job (VehicleOutOfControlMoveJob) and reads terrain and net search structures as read-only. If you modify terrain or net search data from other systems, make sure proper reader/writer registration is maintained to avoid race conditions. - Adjustments to vehicle physics (grip/braking, gravity, number of sub-steps, damping factors) are embedded in the per-vehicle data (CarData) and in constants inside the job (e.g., num2, num, gravity). Changing those requires understanding of the multi-step integrator used here. - If adding new network geometry types used by the NetIterator, follow the patterns used for Node/Orphan and Edge geometries: provide bounds, triangle/segment decomposition, and appropriate prefab composition widths/heights so GetGroundHeight can compute correct ground intersections.