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
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