Index out of range error when using CollisionWorld.CastRay in Netcode project

I have a game built on Entities and Netcode, where I am now attempting to implement raycasting to select targets in the game.

I’m using CollisionWorld.CastRay to do this, however I’m encountering an issue that seems to be within the Unity internals, or at least based on what I can tell from the stacktrace.

Here’s the System being used to trigger the call to CastRay

using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using UnityEngine;
using RaycastHit = Unity.Physics.RaycastHit;

namespace VagueGamerStudios.Selection
{
    public partial class SelectionSystem : SystemBase
    {
        private Camera _mainCamera;
        private CollisionWorld _collisionWorld;
        private PhysicsWorldSingleton _physicsWorldSingleton;

        protected override void OnCreate()
        {
            _physicsWorldSingleton = SystemAPI.GetSingleton<PhysicsWorldSingleton>();
        }

        protected override void OnUpdate()
        {
            if (UnityEngine.Input.GetMouseButtonUp(0))
            {
                TrySelect();
            }
        }

        private void TrySelect()
        {
            _collisionWorld = _physicsWorldSingleton.CollisionWorld;
            _mainCamera = MainGameObjectCamera.Instance;
            
            var ray = _mainCamera.ScreenPointToRay(UnityEngine.Input.mousePosition);
            var rayStart = ray.origin;
            var rayEnd = ray.GetPoint(100f);

            var hasHit = RayCast(rayStart, rayEnd, out var hit);

            if (!hasHit)
            {
                return;
            }
            
            var hitEntity = _physicsWorldSingleton.PhysicsWorld.Bodies[hit.RigidBodyIndex].Entity;

            if (!EntityManager.HasComponent<SelectableTarget>(hitEntity))
            {
                return;
            }
            
            Debug.Log($"Hit on entity {hitEntity}");
            EntityManager.AddComponent<SelectableTarget>(hitEntity);
        }

        private bool RayCast(float3 rayStart, float3 rayEnd, out RaycastHit hit)
        {
            var raycastInput = new RaycastInput
            {
                Start = rayStart,
                End = rayEnd,
                Filter = CollisionFilter.Default
            };

            Debug.Log($"RayCast start: {rayStart}, end: {rayEnd}");

            return _collisionWorld.CastRay(raycastInput, out hit);
        }
    }
}

The log I get right before the CastRay call is

RayCast start: float3(2.17226f, 3.340773f, 7.319185f), end: float3(14.39794f, -27.12375f, 101.7779f)

However I get the following error:

IndexOutOfRangeException: Index 4 is out of range of '0' Length.
Unity.Collections.NativeArray`1[T].FailOutOfRangeError (System.Int32 index) (at <0900e0d4bb644dafbfd59eb7fd222a68>:0)
Unity.Physics.Broadphase+BvhLeafProcessor.RayLeaf[T] (Unity.Physics.RaycastInput input, System.Int32 rigidBodyIndex, T& collector) (at ./Library/PackageCache/com.unity.physics/Unity.Physics/Collision/World/Broadphase.cs:872)
Unity.Physics.BoundingVolumeHierarchy.Raycast[TProcessor,TCollector] (Unity.Physics.RaycastInput input, TProcessor& leafProcessor, TCollector& collector) (at ./Library/PackageCache/com.unity.physics/Unity.Physics/Collision/Geometry/BoundingVolumeHierarchy.cs:1391)
Unity.Physics.Broadphase.CastRay[T] (Unity.Physics.RaycastInput input, Unity.Collections.NativeArray`1[T] rigidBodies, T& collector) (at ./Library/PackageCache/com.unity.physics/Unity.Physics/Collision/World/Broadphase.cs:784)
Unity.Physics.CollisionWorld.CastRay[T] (Unity.Physics.RaycastInput input, T& collector) (at ./Library/PackageCache/com.unity.physics/Unity.Physics/Collision/World/CollisionWorld.cs:1433)
Unity.Physics.QueryWrappers.RayCast[T] (T& target, Unity.Physics.RaycastInput input, Unity.Physics.RaycastHit& closestHit) (at ./Library/PackageCache/com.unity.physics/Unity.Physics/Collision/Queries/Collidable.cs:664)
Unity.Physics.CollisionWorld.CastRay (Unity.Physics.RaycastInput input, Unity.Physics.RaycastHit& closestHit) (at ./Library/PackageCache/com.unity.physics/Unity.Physics/Collision/World/CollisionWorld.cs:1413)
VagueGamerStudios.Selection.SelectionSystem.RayCast (Unity.Mathematics.float3 rayStart, Unity.Mathematics.float3 rayEnd, Unity.Physics.RaycastHit& hit) (at Assets/VagueGamerStudios/Selection/SelectionSystem.cs:67)
VagueGamerStudios.Selection.SelectionSystem.TrySelect () (at Assets/VagueGamerStudios/Selection/SelectionSystem.cs:38)
VagueGamerStudios.Selection.SelectionSystem.OnUpdate () (at Assets/VagueGamerStudios/Selection/SelectionSystem.cs:24)
Unity.Entities.SystemBase.Update () (at ./Library/PackageCache/com.unity.entities/Unity.Entities/SystemBase.cs:418)
Unity.Entities.ComponentSystemGroup.UpdateAllSystems () (at ./Library/PackageCache/com.unity.entities/Unity.Entities/ComponentSystemGroup.cs:723)
UnityEngine.Debug:LogException(Exception)
Unity.Debug:LogException(Exception) (at ./Library/PackageCache/com.unity.entities/Unity.Entities/Stubs/Unity/Debug.cs:17)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at ./Library/PackageCache/com.unity.entities/Unity.Entities/ComponentSystemGroup.cs:728)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at ./Library/PackageCache/com.unity.entities/Unity.Entities/ComponentSystemGroup.cs:687)
Unity.Entities.SystemBase:Update() (at ./Library/PackageCache/com.unity.entities/Unity.Entities/SystemBase.cs:418)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at ./Library/PackageCache/com.unity.entities/Unity.Entities/ScriptBehaviourUpdateOrder.cs:523)

The only thing of note is that if I click the skybox in the game rather than anything with a collider. I get the Debug Log line, but no error. So I’m wondering if it’s something to do with the way I’ve setup my Prefabs with colliders. They’re using a simple Rigidbody component at the moment.

I don’t think what I’m trying to do is more than simple Raycast behavour, so I’m certain I’m doing something stupid, but I’m a bit stumped as even stepping through the code quickly takes me into Unity internals.

Any pointers would be greatly appreciated.

This was due to not fetching the PhysicsWorldSingleton on each frame. Once I’d done that it worked as expected