Batched raycaster utility for Unity. Collects raycast requests from any number of listeners, runs them as a single RaycastCommand batch across worker threads, and routes each listener its own results back. Use it anywhere you have many raycasts to do per frame — line-of-sight, sensors, projectiles — and don't want N individual main-thread Physics.Raycast calls.
It's used by Visioncast's managed path (Visioncast's data-oriented path owns its own Burst raycast batch), but it has no dependency on Visioncast — anything that needs grouped raycasts can be a listener.
Listeners submit a batch of requests via Schedule. Each tick, the raycaster gathers every listener's requests, builds one NativeArray<RaycastCommand>, and schedules it with RaycastCommand.ScheduleBatch. When the job completes, results are sliced back out to the listener that asked for them. Command/hit buffers are persistent and grow on demand, so the per-frame path allocates nothing.
The raycaster is driven externally rather than self-ticking, so you decide when the work happens — from FixedUpdate, a fixed step, or a central scheduler.
Implement IScheduledRaycastListener, submit requests, and read the results back in the callback:
var requests = new List<DataScheduledRaycastRequest>
{
new DataScheduledRaycastRequest
{
SourcePosition = origin,
Direction = dir,
MaxDistance = range,
LayerMask = mask
}
};
RaycastManager.ScheduledRaycaster.Schedule(this, requests);Then drive the raycaster once per cycle. Two paths:
- Synchronous — schedule and complete in one call. Simple; the raycast cost lands on the main thread.
RaycastManager.TickRaycasts(delta);
- Deferred — split the schedule and completion so the job runs on worker threads across the gap. Call
ScheduleRaycasts()after submitting requests, thenCompleteRaycasts()at a point where the physics scene hasn't moved (e.g. bracketing yourPhysics.Simulatestep). Hides the raycast cost off the main thread.RaycastManager.CompleteRaycasts(); // finish last cycle's batch, distribute // ...submit this cycle's requests... RaycastManager.ScheduleRaycasts(); // fire this cycle's batch
Static entry points and the singleton ScheduledRaycaster instance. Exposes TickRaycasts (synchronous) and the ScheduleRaycasts / CompleteRaycasts phase split (deferred).
Implemented by anything that wants grouped raycasts. Receives its RaycasterResults and a ReceiveScheduledRaycasterResults callback when its batch completes (and OnEmptyRaycastRequestResult when it scheduled nothing this cycle).
A single raycast request — source position, direction, max distance, and layer mask. Listeners submit a list of these per cycle.
The package ships edit mode and play mode tests under Tests/. To run them, add the package to the
testables array of your project's Packages/manifest.json — Unity only surfaces a package's tests
when it is listed there:
"testables": [ "com.galaxygourd.raycast" ]They then appear in Window > General > Test Runner:
- EditMode (
GG.Raycast.EditorTests) — theGroupedRequestHandlerscheduling contract: request collection, duplicate-listener handling, and which hooks fire for the synchronous vs deferred tick. - PlayMode (
GG.Raycast.Tests) — the batch raycaster against a real physics scene: per-listener result slicing, layer mask / max distance / direction fidelity, buffer growth and disposal, and the deferred schedule-then-complete cycle.
Headless: Unity -batchmode -nographics -projectPath <project> -runTests -testPlatform EditMode|PlayMode -testResults results.xml.