InvalidOperationException on Raycast

I am trying to do a simple raycast to the object I am facing. The only physics related things in my scene are some entities with physics shapes and a system that casts the ray.

However, this will result in the Exception below about some NativeArray.
Is there anything else I need to do first before this will work? Some setup steps etc.?
I am using Unity Physics 0.2.4.

[ClientLogic, UpdateAfter(typeof(CameraControllerSystem)), UpdateAfter(typeof(BuildPhysicsWorld))]
public class CalculateTargetSystem : ComponentSystem
{
    PhysicsWorld physicsWorld;

    const float MAX_TARGET_DISTANCE = 15f;

    protected override void OnCreate()
    {
        physicsWorld = World.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld;
    }


    protected override void OnUpdate()
    {
        Entities.ForEach((ref LocalToWorld ltw, ref Target target) =>
        {
            RaycastInput raycastInput = new RaycastInput
            {
                Start = ltw.Position,
                End = ltw.Position + ltw.Forward * MAX_TARGET_DISTANCE,
                Filter = CollisionFilter.Default
            };

            if (physicsWorld.CollisionWorld.CastRay(raycastInput, out var raycastHit))
                UnityEngine.Debug.Log("A"); // target.Value = physicsWorld.Bodies[raycastHit.RigidBodyIndex].Entity;
            else
                UnityEngine.Debug.Log("B");
        });
    }
}

Looks like your system runs after the BuildPhysicsWorld system, but not after all jobs of the BuildPhysicsWorld system are finished. You might want to wait for the BuildPhysicsWorld.FinalJobHandle, or convert your system to a JobComponentSystem which will give you the inputDeps in your OnUpdate() call to which you can hook after, to avoid sync points. Let me know if it works for you!

1 Like

That doesn’t seem to solve it. It is logging True, but I still get the same Exception each frame.

        World.GetExistingSystem<BuildPhysicsWorld>().FinalJobHandle.Complete();
        UnityEngine.Debug.Log(World.GetExistingSystem<BuildPhysicsWorld>().FinalJobHandle.IsCompleted);
        Entities.ForEach((ref LocalToWorld ltw, ref Target target) =>
        {
            ...
        });

Hmm, you are doing no different that the VehicleMechanics system in the RaycastCar demo. I notice you are running Unity Physics 0.2.4 and entities 0.3.0. Does the error still happen if you upgrade Unity Physics to the latest 0.2.5?

I was able to reproduce it both with physics 0.2.4 and physics 0.2.5 even in an empty scene with just a camera and a cube.

Ah I think I know what’s going on. You cached PhysicsWorld once and it’s a value type, so a copy is created and it’s empty. Try caching BuildPhysicsWorld and getting the PhysicsWorld from it at the point where you need it (after the final job handle is completed).

4 Likes

Wow, that actually fixed it. Can’t believe it was that simple.
Thanks a lot! :slight_smile: Would never have guessed that this was the problem.

1 Like