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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Trying to replicate performant Schedule Raycast example and getting weird results.

Discussion in 'Entity Component System' started by FederalRazer89, Dec 3, 2021.

  1. FederalRazer89

    FederalRazer89

    Joined:
    Nov 24, 2019
    Posts:
    83
    Hello

    I have been trying to get a efficient way to raycast in ECS and a lot of my logics will be dependent on how well i can get raycast to perform. I have been able to do standard raycast and raycast job that is one ray per job.
    And now i got ScheduleBatchRayCast to work with a bit weird results, got it work mostly by trying to solve the errors that i encountered in a naive way.

    I have mostly based my code on the cast performance example, i know i have done something wrong. The documentation mention the use of JobComponentSystem, but i thought it would be deprecated according to some forums.

    I am a bit unsure of how to proceed, any suggestions on what to do would be helpful and would be very happy. Unless someone points of a better way, then i will try to make my code work in JobComponentSystem, just hoping i will not take a month to get it to work.

    upload_2021-12-3_4-22-43.png

    raycastAmount = 10000

    Code (CSharp):
    1.     private BuildPhysicsWorld buildPhysicsWorldSystem;
    2.  
    3.     protected override void OnCreate()
    4.     {
    5.  
    6.         buildPhysicsWorldSystem = World.GetExistingSystem<BuildPhysicsWorld>();
    7.  
    8.     }
    9.  
    10.     protected override void OnUpdate()
    11.     {
    12.  
    13.         var collisionWorld = buildPhysicsWorldSystem.PhysicsWorld.CollisionWorld;
    14.         var raycastJob = new RaycastJob() { collisionWorld = collisionWorld };
    15.  
    16.  
    17.         Entities.ForEach((ref ECSRaycastTestingData ecsRaycastTestingData, in Translation translation) =>
    18.         {
    19.             NativeArray<RaycastInput> raycastInputs = new NativeArray<RaycastInput>(ecsRaycastTestingData.raycastAmount, Allocator.TempJob);
    20.             NativeArray<RaycastHit> raycastHitList = new NativeArray<RaycastHit>(ecsRaycastTestingData.raycastAmount, Allocator.TempJob);
    21.             NativeArray<JobHandle> jobHandles = new NativeArray<JobHandle>(ecsRaycastTestingData.raycastAmount, Allocator.TempJob);
    22.  
    23.             JobHandle dependency = new JobHandle();
    24.  
    25.             for (int i = 0; i < ecsRaycastTestingData.raycastAmount; i++)
    26.             {
    27.                 float angle = 36 * i;
    28.                 float3 startPos = math.mul(quaternion.RotateY(angle), new float3(0, 0, 0.25f));
    29.  
    30.                 raycastInputs[i] = new RaycastInput()
    31.                 {
    32.                         Start = translation.Value + startPos,
    33.                         End = translation.Value + (startPos + new float3(0, -5, 0)),
    34.                         Filter = CollisionFilter.Default
    35.  
    36.                 };
    37.  
    38.             };
    39.             var scheduleBatchRayCast = ScheduleBatchRayCast(collisionWorld, raycastInputs, raycastHitList);
    40.             scheduleBatchRayCast.Complete();
    41.  
    42.             dependency = JobHandle.CombineDependencies(jobHandles);
    43.             dependency = JobHandle.CombineDependencies(dependency, scheduleBatchRayCast);
    44.  
    45.  
    46.             dependency.Complete();
    47.  
    48.  
    49.             jobHandles.Dispose();
    50.             raycastInputs.Dispose();
    51.             raycastHitList.Dispose();
    52.  
    53.  
    54.         }).WithoutBurst().Run();
    55.  
    56.         buildPhysicsWorldSystem.AddInputDependencyToComplete(Dependency);
    57.  
    58.     }
     
  2. apaxnid

    apaxnid

    Joined:
    Nov 18, 2012
    Posts:
    34
    You can't schedule jobs inside another job, move schedulling part outside of Entities.ForEach(...) it will look something like this
    Code (CSharp):
    1.  
    2. var physicsWorld = buildPhysicsWorldSystem.PhysicsWorld;
    3. Entities.ForEach((ref ECSRaycastTestingData ecsRaycastTestingData, in Translation translation) =>
    4.         {
    5.             int count = ecsRaycastTestingData.raycastAmount;
    6.             var raycastInputs = new NativeArray<RaycastInput>(count, Allocator.Temp);
    7.             var raycastHitList = new NativeArray<RaycastHit>(count, Allocator.Temp);
    8.             for (int i = 0; i < ecsRaycastTestingData.raycastAmount; i++)
    9.             {
    10.                 float angle = 36 * i;
    11.                 float3 startPos = math.mul(
    12.                     quaternion.RotateY(angle),
    13.                     new float3(0, 0, 0.25f));
    14.              
    15.                 raycastInputs[i] = new RaycastInput()
    16.                 {
    17.                     Start = translation.Value + startPos,
    18.                     End = translation.Value + (startPos + new float3(0, -5, 0)),
    19.                     Filter = CollisionFilter.Default
    20.                 };
    21.             };
    22.             for (int i = 0; i < ecsRaycastTestingData.raycastAmount; i++)
    23.             {
    24.                 physicsWorld.CastRay(raycastInputs[i], out var hit);
    25.                 raycastHitList[i] = hit;
    26.             }
    27.         }).Run();
    28.  
    But this way you can't retrieve results of your raycasts outside this job
     
    Last edited: Dec 8, 2021
    FederalRazer89 likes this.
  3. FederalRazer89

    FederalRazer89

    Joined:
    Nov 24, 2019
    Posts:
    83
    Thanks for the respons, you version is faster then mine. But i am what i am trying to test is to see if i can achieve higher raycast performance which is specified at the bottom of the documentation titled Cast Performance
    Link: https://docs.unity3d.com/Packages/com.unity.physics@0.3/manual/collision_queries.html
    My current testing might be the wrong approach, but i have done some test were i did raycast on more threads, but got very bad performance. The documentation which i have linked describes a way to batch several raycast jobs together then schedule them.

    I am still fairly new to how the syntaxes in ECS should be use.
     
  4. apaxnid

    apaxnid

    Joined:
    Nov 18, 2012
    Posts:
    34
    Cast performance states that for better performance you should use raycast in burst compiled job, thats all
     
    FederalRazer89 likes this.
  5. FederalRazer89

    FederalRazer89

    Joined:
    Nov 24, 2019
    Posts:
    83
    Ok, then i just interpreted it wrong. But i got some idea that i will test.

    Going to check if i can try and convert my test into more jobs and burst

    Thanks for the clarification.