Search Unity

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:
    35
    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:
    35
    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.