Skip to content

Game.Zones.RaycastJobs.FindZoneBlockJob

Assembly:
Namespace: Game.Zones

Type: struct (nested in static class RaycastJobs)

Base: Unity.Jobs.IJobParallelFor

Summary:
A Burst-compiled parallel job that takes a set of raycast inputs and terrain raycast results and attempts to resolve a zone block + cell hit for each ray. For each ray it: - verifies the raycast type mask includes zones, - uses the terrain hit position to iterate a NativeQuadTree of zone blocks, - computes the cell index inside a found block, - checks cell visibility/shared flags, - updates the RaycastResult owner and hit cell index, adjusts normalized distance, and - accumulates the result into a NativeAccumulator (parallel writer). This job is intended to run as part of the game's raycast pipeline to attach zone information to raycast hits.


Fields

  • public NativeArray<RaycastInput> m_Input
    [ReadOnly] Input ray descriptions (lines, type masks, etc.). The job uses these to determine the ray line length and type mask. The index used inside Execute is index2 = index % m_Input.Length, so the caller must ensure scheduling and array sizes are consistent.

  • public ComponentLookup<Block> m_BlockData
    [ReadOnly] ComponentLookup to read Block component data for block entities visited during quad-tree iteration.

  • public BufferLookup<Cell> m_Cells
    [ReadOnly] Buffer lookup for per-block cell buffers. Used to test cell flags and access per-cell state.

  • public NativeQuadTree<Entity, Bounds2> m_SearchTree
    [ReadOnly] QuadTree of zone block entities keyed by 2D bounds. The job constructs an iterator and calls Iterate on this tree to locate candidate blocks at the hit position.

  • public NativeArray<RaycastResult> m_TerrainResults
    [ReadOnly] Precomputed terrain raycast results. The job uses these (indexed by the job index) to obtain the hit position and to start from a terrain hit owner before attempting to find a zone owner.

  • public NativeAccumulator<RaycastResult>.ParallelWriter m_Results
    [NativeDisableContainerSafetyRestriction] Parallel writer for accumulating resulting RaycastResult entries. Note the container safety restriction attribute — callers must ensure proper usage and avoid races when reading/writing the accumulator.

Properties

  • None (this job is a plain struct with public fields used to pass data in/out for the job).

Constructors

  • public FindZoneBlockJob()
    The struct uses the default compiler-generated constructor. Users must populate the public fields before scheduling the job.

Methods

  • public void Execute(int index)
    Implementation of IJobParallelFor. For the given index:
  • Determines the corresponding RaycastInput (index2 = index % m_Input.Length).
  • Fetches the terrain RaycastResult at index.
  • If the ray's TypeMask includes zones and the terrain result has a non-null owner, it creates an Iterator with the hit XZ position, block component lookup and cell buffer lookup and iterates the NativeQuadTree to find a matching block.
  • If a block is found and the computed cell index is inside block bounds and the cell is visible (cell state check: (m_State & (CellFlags.Shared | CellFlags.Visible)) == CellFlags.Visible), it:
    • sets value.m_Owner to the block entity,
    • writes the cell index into value.m_Hit.m_CellIndex,
    • reduces value.m_Hit.m_NormalizedDistance by 1f / max(1f, length(raycastInput.m_Line)) (moves the normalized distance a bit to prefer zone hit over terrain), and
    • accumulates the result into m_Results using index2 as the key.
  • Notes:

    • Uses math.all and Mathf length helpers (via Colossal.Mathematics/Unity.Mathematics).
    • Assumes m_TerrainResults length and the scheduled iteration count are consistent (the code reads m_TerrainResults[index]).
  • Iterator (private nested struct) methods:

  • public bool Intersect(Bounds2 bounds)
    Returns whether the provided bounds intersects the iterator's m_Position (2D) using MathUtils.Intersect. This is used by the quad-tree to do quick culling.

  • public void Iterate(Bounds2 bounds, Entity blockEntity)
    Called for each candidate block in the quad-tree. If bounds intersect the hit position:

    • reads the Block component for blockEntity,
    • computes a 2D cell index inside the block via ZoneUtils.GetCellIndex(block, m_Position),
    • checks the index falls inside block.m_Size and whether the corresponding cell buffer entry has CellFlags.Visible (not shared-only),
    • if ok stores blockEntity into m_Block and the cell index into m_CellIndex for later consumption by Execute.

Attributes: - The job struct is marked with [BurstCompile], so it can be compiled by the Burst compiler when scheduled.

Usage Example

// Example scheduling pattern — adapt to your calling code and lifetime rules.
using Unity.Jobs;
using Unity.Collections;

// prepare inputs
var rayInputs = new NativeArray<RaycastInput>(N, Allocator.TempJob);
// fill rayInputs...
var terrainResults = new NativeArray<RaycastResult>(N, Allocator.TempJob);
// fill terrainResults...

// prepare container for accumulated results
var accumulator = new NativeAccumulator<RaycastResult>(N, Allocator.TempJob); // example constructor; use actual API available in your environment
var parallelWriter = accumulator.AsParallelWriter();

// build the job
var job = new RaycastJobs.FindZoneBlockJob
{
    m_Input = rayInputs,
    m_BlockData = /* ComponentLookup<Block> filled from system (set via SystemState or ComponentSystem) */,
    m_Cells = /* BufferLookup<Cell> from system */,
    m_SearchTree = /* NativeQuadTree<Entity, Bounds2> prepared earlier */,
    m_TerrainResults = terrainResults,
    m_Results = parallelWriter
};

// schedule: ensure jobCount matches terrainResults length if terrainResults is indexed by the raw job index
int jobCount = terrainResults.Length;
JobHandle handle = job.Schedule(jobCount, 64, default);
handle.Complete();

// read accumulated results from accumulator...
// cleanup
accumulator.Dispose();
rayInputs.Dispose();
terrainResults.Dispose();

Notes and Caveats: - The job disables safety checks for m_Results (NativeDisableContainerSafetyRestriction) — be careful and follow correct patterns for parallel accumulation to avoid data races. - Ensure the ComponentLookup and BufferLookup instances are created with correct "isReadOnly" semantics expected by the job and updated from the appropriate System (e.g., via SystemState.GetComponentLookup(true) / GetBufferLookup(true)). - The code uses index2 = index % m_Input.Length while reading m_TerrainResults[index]. To avoid indexing issues, schedule the job such that m_TerrainResults.Length >= scheduled jobCount, and that modulo usage is intended for repeating inputs across a longer results array. If unsure, set jobCount == m_TerrainResults.Length and ensure m_Input.Length divides appropriately or is intended to be cycled. - Because the job uses NativeQuadTree iteration, the quad-tree and component/buffer lookups must remain valid and not be modified concurrently while the job runs.