Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Bug How do I parse multiple hits from the results of RaycastCommand.ScheduleBatch()?

Discussion in 'Physics' started by Interjection, Jun 25, 2020.

  1. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    I'm trying to perform "Physics.RaycastNonAlloc()" with the multi-threaded Job system, using Unity's RaycastCommand.ScheduleBatch(). I want to get several RaycastHits per ray.

    At first glance it looks like it only supports 1 result per ray. However, RaycastCommand has a maxHits property.

    Here's some mockup code with 1k rays all going down from [0,0,0]:

    Code (CSharp):
    1. int queueLength = 1000;
    2. int maxHits = 50;
    3.  
    4. NativeArray<RaycastCommand> commands = new NativeArray<RaycastCommand>(queueLength, Allocator.TempJob);
    5. NativeArray<RaycastHit> results = new NativeArray<RaycastHit>(queueLength*maxHits, Allocator.TempJob);
    6.  
    7. for (int i = 0; i < queueLength; i++) {
    8.     commands[i] = new RaycastCommand(Vector3.zero, Vector3.down, Mathf.Infinity, ~0, maxHits);
    9. }
    10.  
    11. Unity.Jobs.JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(Unity.Jobs.JobHandle));
    12. handle.Complete();
    13.  
    14. //parse results (associate X number of results with the correct command)
    15.  
    16. commands.Dispose();
    17. results.Dispose();
    I assumed that command [0] would store its results in [0-49], command [1] would store in [50-99] etc.

    So if I for example wanted the results of command [12] I would step from 12*maxHits until 13*maxHits-1 in the results array, stopping at the first null collider.

    But seems like that doesn't work correctly. How am I supposed to parse the results?

    Or does RaycastCommand.ScheduleBatch() not support multiple hits per ray?
     
    CPlusSharp22 likes this.
  2. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    Actually, after some more testing it seems like I got it right in my post above.
    Several hits per raycast is supported!
    (I'll come back and say otherwise if I later discover that it was wrong after all.)
     
  3. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    Hm, several hits per raycast is supported on paper. But after testing a lot I can't get more than one hit per ray for some reason, even though I have 50 max hits on all commands sent to ScheduleBatch().

    I've made the following test code:

    Code (CSharp):
    1. int maxHits = 50;
    2. //[...] populate native arrays
    3. Unity.Jobs.JobHandle handle = RaycastCommand.ScheduleBatch(commands, results, 1, default(Unity.Jobs.JobHandle));
    4. handle.Complete();
    5. for (int i = 0; i < commands.Length; i++) {
    6.     int hits = 0;
    7.     for (; hits < maxHits; hits++) {
    8.         if (results[i*maxHits + hits].collider==null) {
    9.             break;
    10.         }
    11.     }
    12.     if (hits==0) {
    13.         Debug.Log("zero");
    14.     } else if (hits==1) {
    15.         Debug.Log("one");
    16.     } else if (hits>=2) {
    17.         Debug.Log("two!! :O");
    18.     }
    19. }
    I get a lot of "zero" or "one" but never a single "two".
    Meanwhile if I do the exact same raycasts using "int hits = Physics.RaycastNonAlloc()" I get plenty of "two".

    Has anyone been able to get several hits from a single ray using RaycastCommand? Is it broken?
     
  4. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    OKAY. This has been mystifying me for a few days now and turns out that this is not even a bug, it is a known limitation that has been known about since 2018 and Unity's documentation has simply not been updated!

    From https://fogbugz.unity3d.com/default.asp?1041352_j87fk47jv1pg5nfe
    "According to our developers, each individual raycast in a batch only does a Raycast single in PhysX which will only return the first hit, and not multiple hits if the ray passes through several objects which would require a different raycast function. The documentation simply doesn't explain this very well."

    This was over two years ago and the bug report ticket is closed. I found out about this in the following thread: https://forum.unity.com/threads/ray...it-regardless-what-you-set-maxhits-to.532738/

    Right now, in Unity's 2019.4 documentation on https://docs.unity3d.com/ScriptReference/RaycastCommand.html it says:
    "The result for a command at index N in the command buffer will be stored at index N * maxHits in the results buffer."
    (For future readers, "2019.4" was released June 9, 2020. Not in 2019.)

    Unity, please make a quick edit in your documentation. There are serious communication issues within your company if you had this reported as a bug two years ago and had the issue closed a month later but the docs was never changed to stop talking about maxHits as if it was a feature.

    You should remove the "maxHits" property from RaycastCommand completely because it is misleading. Setting it to any value above 1 does nothing. Even if you "intend to fix this" just remove it, it's been two years already and could be another two. If it can be fixed simply add maxHits back in once it works.
     
    Hobodi, kbop2000 and MNNoxMortem like this.
  5. Interjection

    Interjection

    Joined:
    Jun 18, 2020
    Posts:
    63
    For the record, I'm moving from the built-in PhysX over to the new Unity Physics where you can raycast in jobs and get multiple hits per ray. My thread with example code about it is here: https://forum.unity.com/threads/aby...ycasting-in-the-new-unity-physics-ecs.924536/

    As a side note, Unity has still not fixed their incorrect RaycastCommand documentation. It's been over two years so I don't know why I had my hopes up, they just don't care. I'm changing this thread's prefix from "Help Wanted" to "Bug".
     
    OndrejP likes this.
  6. CPlusSharp22

    CPlusSharp22

    Joined:
    Dec 1, 2012
    Posts:
    111
    The hell unity?
    BoxcastCommand and SpherecastCommand also dont support multiple hits. I dont understand. At least you cant specify maxhits misleadingly.
     
    OndrejP likes this.
  7. Darkgaze

    Darkgaze

    Joined:
    Apr 3, 2017
    Posts:
    374
    This is outrageous.
    Development for months based on this has been destroyed due to this missleading information.
    In fact, now I can't detect several objects in one area using RaycastCommand, because I need to run Complete() for the first pass, add rays for the second pass where the old ones hit.... what the???

    Writing another bug report, writing bug reports in the documentation.
     
  8. Darkgaze

    Darkgaze

    Joined:
    Apr 3, 2017
    Posts:
    374
    While we wait for this fix... I created a jobified and optimized script that you can use to get the correct hits.

    It's as easy as adding the script to your project and calling:
    RaycastCommandMultihit.ScheduleBatch(...) and it will return the correct results.

    I created a gumroad pack as I generally do for these kind of complicated stuff that I need to upload.
    You can download the script and use it freely. All the information is here:

    https://lidiamartinez.gumroad.com/l/wKyFk
     
  9. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    427
    I do think Unity should not just commit a single hit version and pretend they have finished this part for years, that's ridiculous
     
  10. TheHrdlicka

    TheHrdlicka

    Joined:
    Jan 25, 2023
    Posts:
    1
    Can anyone please at least confirm that this is still the case in 2021.3, and the RaycastCommands still only support one hit, and the documentation is still wrong?

    I'd at least like to know whether the issue is at my side, since I don't really have much experience with Jobs and during debugging, before I've encountered this thread, my code has become pretty messy, or whether I'm trying to do something that's actually not even supported AND still has plainly wrong documentation.
     
    Arathorn_J likes this.
  11. Arathorn_J

    Arathorn_J

    Joined:
    Jan 13, 2018
    Posts:
    47
    RaycastCommands and batch scheduling raycasts works properly for multiple hits in 2023.1.0f1.

    So how it works is when you schedule the batch you set your max hits and ensure your results array has the number of commands * the number of max hits (in this example 4 maxhits):



    var results = new NativeArray<RaycastHit>(rayCastCommands.Length * 4, Allocator.TempJob);

    JobHandle handle = RaycastCommand.ScheduleBatch(rayCastCommands.AsArray(), results, 1, 4, default(JobHandle));
    handle.Complete();

    When you handle the results you can tie it back to the original command by incrementing the original sender command index by 4 (in my example above for 4 maxhits. What you end up with in the results is each array filled by the original command with either a hit or a null result which goes from closest to farthest.

    So if you had 2 hits in a 100 meter raycast you might have the first position say at 17 meters, the second position at 20 meters and the third and the fourth could be null.

    This is in the documentation but I'm not sure if it was not working properly till now.