This script is free but if you find it useful, please consider supporting my work!
RaycastCommand.ScheduleBatch with parameter maxHits > 0 doesn't work. It always returns just one hit even though it is documented and in the API. Bug reports have been closed because it happens... "By Design".
With this jobified / multithreaded (but obviously a bit slower) version you will be able to call:
RaycastCommandMultihit.ScheduleBatch(...) with the same parameters as the original one plus some more, the same rays and result arrays, and receive correct results.
How fast is it?
For 1000 rays and 10 hits, you can get a 0.25ms (in editor profiler) instead of 0.1 of the original version. The less rays and hits, the faster the process.
What does the package contain?
A folder with several items.
- The main RaycastCommandMultihit.cs which you can put wherever you want (read requirements if you delete the rest of the files and put it somewhere else)
- A test scene, material, and a test script/component that is attached to an object in the scene and be used to compare efficiency between this method and the new one.
Available parameters on the test component: ray distance, number of rays, number of hits, batch size of the jobs and chosing which method to use (multihit or the native one that fails). All rays are thrown from the same place, and the first can be displayed using a checkbox in the component.
Requirements - How to use
Supports Unity 2018, 2019, 2020 and 2021 (and probably more, unless they make RaycastCommand work properly).
There are two requirements for this code: The use of unsafe code and the use of Burst package (and Jobs if you are using v2018).
This code performs unsafe operations not allowed in jobs to hack the access to each RaycastHit, another famous limitation to jobs and RaycastCommand.
Add the folder to your project. You will probably have compilation errors. Ignore them.
Install Burst package using the Window -> Package Manager.
Then check that the assembly definition file that is included in the folder has "Allow Unsafe Code" enabled and the Burst package is referenced.
If you don't want to use this assembly file, you can delete it and use your own up in the hierarchy and add these two things to it, or even enabling Allow Unsafe Coe in your Player Settings globally.
If you don't want to add the Burst package , you can delete the [BurstCompile] line before the job definition and from the assembly definition file, but it will be slower.
In your scripts you can now call : RayastCommandMultihit.ScheduleBatch(...).
Stay tuned if you downloaded it, improvements will be uploaded here.
Known problems / Future TODO list:
- Original input RaycastCommands are reused to make the process faster. But I am only able to restore the original FROM position without creating a copy of the original array, the distances and maxhits are set to 0. Generally you won't need these anymore but in case you want to keep them, make a copy yourself before calling ScheduleBatch.
- Stop the process beforehand if all hits failed. This would make the process a lot faster in cases where most of the rays fail, but sadly since this is a chain of jobs, no boolean or counter is allowed inbetween to stop calling the jobs before all are finished. I need to find a way to do this. I'm just making empty RaycastCommands for the next steps, which accelerates the process a bit.
- Try to avoid having the "assembly + unsafe" requirements. The only way to check if a Hit didn't happen is to check if the collider inside the hit is null, and this is not allowed inside jobs, because it makes a call to a UnityEngine class.