Skip to content

Game.Common.RaycastSystem

Assembly: Assembly-CSharp
Namespace: Game.Common

Type: class

Base: GameSystemBase

Summary:
RaycastSystem is an ECS system responsible for performing multi-target raycasts across game data (terrain, water, zones, areas, nets, static/moving objects, routes, labels, icons, water sources, etc.). It collects RaycastInput entries submitted by callers, schedules a complex set of Burst-compiled jobs (using many specialized RaycastJobs) to evaluate hits in parallel, and accumulates RaycastResult entries per input. The system integrates with a number of search/culling subsystems (zone/area/net/object/route search trees, pre-culling, icon clustering, terrain & water systems) and uses Unity DOTS patterns (NativeLists, NativeQueues, NativeAccumulator, JobHandles). Use AddInput to queue a raycast, and GetResult to read results (after the system has completed its work).

Key points: - Multi-target: supports many TypeMask targets (Terrain, Water, Zones, Areas, Net, Lanes, Static/MovingObjects, Labels, Icons, Routes, WaterSources, etc.). - Uses camera FOV to expand lane queries when needed (m_LaneExpandFovTan). - Internally manages persistent NativeList buffers for inputs and results—these are disposed on system destroy. - Scheduling is asynchronous and depends on Unity JobHandles; CompleteRaycast ensures dependencies are finished and clears input buffers. - Designed for high performance; many internals are Burst compiled and intended to run on worker threads.


Fields

  • private EntityQuery m_TerrainQuery
    Used to locate the Terrain singleton entity in the world (used when raycasting terrain and water).

  • private EntityQuery m_LabelQuery
    Query used when raycasting label geometry (e.g., district labels).

  • private EntityQuery m_IconQuery
    Query used for icon archetype chunks when evaluating notification/icon hits.

  • private EntityQuery m_WaterSourceQuery
    Query used to iterate water source entities when TypeMask.WaterSources is requested.

  • private Game.Zones.SearchSystem m_ZoneSearchSystem
    Reference to the zone search system used for zone raycasts.

  • private Game.Areas.SearchSystem m_AreaSearchSystem
    Reference to the area search system used for area raycasts.

  • private Game.Net.SearchSystem m_NetSearchSystem
    Reference to the net search system used for net and lane raycasts.

  • private Game.Objects.SearchSystem m_ObjectsSearchSystem
    Reference to the objects search system used for static/moving objects raycasts.

  • private Game.Routes.SearchSystem m_RouteSearchSystem
    Reference to the route search system used for route waypoints/segments raycasts.

  • private IconClusterSystem m_IconClusterSystem
    Reference to icon cluster data used for icon raycasts.

  • private CityConfigurationSystem m_CityConfigurationSystem
    Provides global city config values (e.g., leftHandTraffic) used by some raycast jobs.

  • private ToolSystem m_ToolSystem
    Used to check editor mode flag (affects job behavior).

  • private PreCullingSystem m_PreCullingSystem
    Provides culling data consumed by static/moving object raycast jobs.

  • private TerrainSystem m_TerrainSystem
    Provides terrain height data and position offset for terrain-based raycasts.

  • private WaterSystem m_WaterSystem
    Provides water surface data used by water-related raycasts.

  • private UpdateSystem m_UpdateSystem
    Used to update to the Raycast system update phase explicitly (m_UpdateSystem.Update(SystemUpdatePhase.Raycast)).

  • private List<object> m_InputContext
    A managed list storing context objects that callers associate with each RaycastInput (used to group results per caller/context).

  • private List<object> m_ResultContext
    A managed list storing the contexts corresponding to m_Result entries (set every OnUpdate to be the snapshot of m_InputContext).

  • private NativeList<RaycastInput> m_Input
    Persistent native list that holds RaycastInput entries queued via AddInput. Allocator.Persistent; cleared on CompleteRaycast.

  • private NativeList<RaycastResult> m_Result
    Persistent native list that holds accumulated raycast results for the current batch; sized to m_Input.Length during OnUpdate.

  • private JobHandle m_Dependencies
    Stores combined JobHandle for scheduled jobs so the system can Complete() when needed.

  • private bool m_Updating
    Flag indicating that an update has been scheduled and results are pending (true between OnUpdate scheduling and job completion).

  • private TypeHandle __TypeHandle
    Internal struct holding many ComponentLookup/BufferLookup/TypeHandle fields used to pass component accessors into jobs. Assigned during OnCreateForCompiler.

  • Nested job structs (defined as private nested types)

  • FindEntitiesFromTreeJob, DequeEntitiesJob, RaycastTerrainJob, RaycastWaterSourcesJob, RaycastResultJob, and many other jobs referenced/created in PerformRaycast. They implement the logic for searching spatial quadtrees, terrain/water raycasts, object extraction, lane/edge/routine raycasts, labels, icons, and result accumulation.

Properties

  • (none public)

The RaycastSystem does not expose public properties. All interactions are performed via AddInput, GetResult and the ECS lifecycle.

Constructors

  • public RaycastSystem()
    Default (parameterless) constructor. Systems are typically created and managed by the DOTS World; do not instantiate manually unless you know how to register it into a World. OnCreate initializes native buffers and grabs references to dependent systems.

Methods

  • protected override void OnCreate()
    Initializes the system: obtains references to required search and support systems, creates entity queries, creates a Terrain entity (singleton) if necessary, allocates persistent NativeLists for inputs and results, and prepares context lists. This runs once when the system is created by the world.

  • protected override void OnDestroy()
    Completes any outstanding dependencies, disposes persistent native allocations (m_Input, m_Result), and performs cleanup. Always allow the system to run its destruction logic to avoid leaks.

  • public void AddInput(object context, RaycastInput input)
    Add a RaycastInput associated with a caller-provided context token. If input.IsDisabled() is true, the input's TypeMask is set to None and it will not participate in raycasts. This method calls CompleteRaycast() to ensure any previously scheduled raycasts are finished before adding new inputs. Inputs are queued into the persistent m_Input NativeList and context stored in m_InputContext. Callers should provide a unique context object to later fetch results with GetResult.

  • public NativeArray<RaycastResult> GetResult(object context)
    After a raycast update completed (CompleteRaycast ensures completion), call this with the context passed to AddInput to obtain a NativeArray slice of RaycastResult entries for that context's inputs. If the context is not found, returns a default/empty NativeArray. The returned array is a subarray of the system's m_Result list (no extra allocation); do not Dispose() it. Results are valid only after CompleteRaycast() (i.e., after jobs have completed).

  • protected override void OnUpdate()
    Schedules raycast processing for the queued inputs. Steps:

  • Forces the UpdateSystem to a specific phase (m_UpdateSystem.Update(SystemUpdatePhase.Raycast)).
  • Calls CompleteRaycast() (to finish any prior run), snapshots input contexts into m_ResultContext, resizes m_Result, and creates a NativeAccumulator for job accumulation.
  • Calls PerformRaycast(accumulator) to create and schedule the actual set of jobs; then schedules RaycastResultJob to copy accumulator results into m_Result.
  • Stores the combined JobHandle in m_Dependencies and marks m_Updating = true. This method does not block; caller must either rely on CompleteRaycast() later or call GetResult after completion.

  • private void CompleteRaycast()
    If an update is pending (m_Updating is true), completes m_Dependencies (blocks until all scheduled jobs are finished), clears the input contexts and m_Input list, and marks m_Updating = false. AddInput calls this automatically to ensure a consistent state before adding new inputs.

  • private JobHandle PerformRaycast(NativeAccumulator<RaycastResult> accumulator)
    Core method that inspects the combined TypeMask and RaycastFlags from queued inputs and composes a complex dependency graph of jobs to produce raycast results. Responsibilities:

  • Acquire camera FOV and compute lane expansion factors.
  • Prepare terrain/water jobs if terrain/water/areas/zones/waterSources are requested.
  • Query spatial search trees (net, objects, lanes, routes) and build entity lists via quadtree iteration jobs.
  • Schedule jobs for moving/static objects, edges, lanes, zones, areas, routes, labels, icons, and water sources, wiring component lookups from __TypeHandle into jobs.
  • Combine and return a JobHandle representing all scheduled work. Important notes:
  • Many temporary NativeLists/Queues are allocated with TempJob and are disposed after job scheduling or when jobs complete via dependency handles.
  • The method integrates with other system readers so it adds respective readers (e.g., m_NetSearchSystem.AddNetSearchTreeReader(jobHandle)).
  • The function returns the final JobHandle; caller is responsible for storing/combining it (OnUpdate stores it in m_Dependencies).

  • private void __AssignQueries(ref SystemState state)
    Compiler helper that can establish entity queries during compiled builds. In this decompiled code it constructs an EntityQueryBuilder but does not set additional queries here.

  • protected override void OnCreateForCompiler()
    Compiler-time helper: invokes base.OnCreateForCompiler, assigns queries and calls __TypeHandle.__AssignHandles to fill component lookups for jobs. This is part of the generated DOTS boilerplate to ensure jobs get the correct handles.

  • public RaycastSystem()
    Parameterless constructor (same as above in Constructors section).

Additional notes about nested job types: - The class defines many private job structs (BurstCompile attributed) such as RaycastTerrainJob, FindEntitiesFromTreeJob, RaycastWaterSourcesJob, RaycastResultJob, DequeEntitiesJob and numerous jobs from other namespaces used in PerformRaycast (Game.Objects.RaycastJobs, Game.Net.RaycastJobs, Game.Zones.RaycastJobs, Game.Areas.RaycastJobs, Game.Routes.RaycastJobs, Game.Notifications.RaycastJobs). These jobs are Burst-compiled and rely on the component lookups passed from __TypeHandle. Modders should not attempt to call these jobs directly; use AddInput/GetResult and the system will schedule them.

Usage Example

// Typical usage from managed code that has access to the DOTS World:
var raycastSystem = World.DefaultGameObjectInjectionWorld
    .GetExistingSystemManaged<Game.Common.RaycastSystem>();

// Prepare a RaycastInput (example values — adapt to your RaycastInput API)
RaycastInput input = default;
input.m_Line = new Line3.Segment(new float3(0, 10, 0), new float3(0, -10, 0));
input.m_Offset = float3.zero;
input.m_TypeMask = TypeMask.Terrain | TypeMask.StaticObjects;
input.m_Flags = RaycastFlags.None;

// Provide a context object to correlate results to this caller (can be any object)
object context = this;

// Submit the input
raycastSystem.AddInput(context, input);

// The system will schedule jobs during the next frame update. To get results:
// Ensure the system completed (CompleteRaycast will block until jobs finish).
raycastSystem.GetResult(context).ForEach((RaycastResult res) =>
{
    // Handle the RaycastResult (res.m_Hit contains hit data, res.m_Owner is hit owner entity).
    Debug.Log($"Hit owner: {res.m_Owner} position: {res.m_Hit.m_HitPosition}");
});

Notes: - Call AddInput for each ray you want to test during the frame. Use a unique context or reuse the same context for grouping. - Call GetResult(context) only after the scheduled jobs have completed (calling CompleteRaycast or ensuring OnUpdate has finished). GetResult returns a NativeArray slice referencing internal buffers—do not Dispose() it. - Avoid calling AddInput frequently without letting the system finish (CompleteRaycast is called internally when adding, and it will block if an update was pending). - RaycastSystem is tightly bound to the game world and other search/culling systems; running it outside the intended world or without valid Camera.main can early-out some work.