Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question CollisionWorld.CastRay() does not work with Collector

Discussion in 'Physics for ECS' started by krooninator, Aug 16, 2022.

  1. krooninator

    krooninator

    Joined:
    Nov 9, 2015
    Posts:
    4
    I have this code snipped which is supposed to detect when an entity has been clicked on.
    Variant A works, which simply returns the closest hit. Variant B does NOT work, even though I use the same ray and a Unity-provided collector.
    What confuses me is that both calls use ClosestHitCollider<RaycastHit> under the hood.
    I tried to use every available collector and even wrote a custom one, none detected any entity.

    Can anybody help me solve this issue? I probably missed something about the inner workings of the Physics package.

    Code (CSharp):
    1.             _currentCollisionWorld = _buildPhysicsWorld.PhysicsWorld.CollisionWorld;
    2.  
    3.             var ray = _mainCamera.ScreenPointToRay(mouse.position.ReadValue());
    4.             var (origin, end) = (ray.origin, ray.GetPoint(1000f));
    5.             Debug.DrawLine(origin, end, Color.blue);
    6.  
    7.             var raycastInput = new RaycastInput
    8.             {
    9.                 Start  = origin,
    10.                 End    = end,
    11.                 Filter = CollisionFilter.Default
    12.             };
    13.             var collector = new ClosestHitCollector<RaycastHit>();
    14.  
    15.             //VARIANT A -> This works!
    16.             if (!_currentCollisionWorld.CastRay(raycastInput, out var closestHit)) return;
    17.             Debug.Log("Variant A!");
    18.  
    19.             //VARIANT B -> This doesn't work!
    20.             if (!_currentCollisionWorld.CastRay(raycastInput, ref collector)) return;
    21.             Debug.Log("Variant B!");
    22. ;
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,732
    Under the hood the out version just uses a collector

    Code (CSharp):
    1. public static bool RayCast<T>(ref T target, RaycastInput input, out RaycastHit closestHit) where T : struct, ICollidable
    2. {
    3.     var collector = new ClosestHitCollector<RaycastHit>(1.0f);
    4.     if (target.CastRay(input, ref collector))
    5.     {
    6.         closestHit = collector.ClosestHit;  // TODO: would be nice to avoid this copy
    7.         return true;
    8.     }
    9.  
    10.     closestHit = new RaycastHit();
    11.     return false;
    12. }
    The issue you're having is you haven't set a max fraction value on the collector. Just use 1 like the out version uses and you should have identical behaviour.
     
    krooninator and Harry-Wells like this.
  3. krooninator

    krooninator

    Joined:
    Nov 9, 2015
    Posts:
    4
    Thank you! That seems to have worked.
    Sometimes you miss the most obvious stuff :)