Search Unity

Should I be able to use PhysicsWorld.CalculateDistance in parallel?

Discussion in 'Physics for ECS' started by Bas-Smit, Mar 12, 2020.

  1. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274
    Below are two systems scheduling jobs that call PhysicsWorld.CalculateDistance which results in this error. Can CalculateDistance not be used in parallel? Using Unity Physics 0.3.0.

    InvalidOperationException: The previously scheduled job Bar:<>c__DisplayClass_OnUpdate_LambdaJob0 writes to the NativeArray <>c__DisplayClass_OnUpdate_LambdaJob0.Data.world.CollisionWorld.m_Bodies.
    You are trying to schedule a new job Foo:<>c__DisplayClass_OnUpdate_LambdaJob0, which writes to the same NativeArray (via <>c__DisplayClass_OnUpdate_LambdaJob0.Data.world.CollisionWorld.m_Bodies).
    To guarantee safety, you must include Bar:<>c__DisplayClass_OnUpdate_LambdaJob0 as a dependency of the newly scheduled job.


    Code (CSharp):
    1.  
    2. using Unity.Collections;
    3. using Unity.Entities;
    4. using Unity.Jobs;
    5. using Unity.Mathematics;
    6. using Unity.Physics;
    7. using Unity.Physics.Systems;
    8. using UnityEngine;
    9.  
    10. class Main : MonoBehaviour
    11. {
    12.     void Start()
    13.     {
    14.         var em = World.All[0].EntityManager;
    15.         em.CreateEntity(typeof(FooComp));
    16.         em.CreateEntity(typeof(BarComp));
    17.     }
    18. }
    19.  
    20. [UpdateAfter(typeof(EndFramePhysicsSystem))]
    21. class Foo : SystemBase
    22. {
    23.     protected override void OnUpdate()
    24.     {
    25.         var s = World.GetExistingSystem<EndFramePhysicsSystem>();
    26.         Dependency = JobHandle.CombineDependencies(s.FinalJobHandle, Dependency);
    27.         var world = World.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld;
    28.        
    29.         Entities
    30.             .ForEach((FooComp c) =>
    31.             {
    32.                 var input = new PointDistanceInput
    33.                 {
    34.                     Filter = CollisionFilter.Default,
    35.                     MaxDistance = 100,
    36.                     Position = float3.zero
    37.                 };
    38.  
    39.                 var hits = new NativeList<DistanceHit>(Allocator.Temp);
    40.                 world.CalculateDistance(input, ref hits);
    41.                
    42.                 foreach (var hit in hits)
    43.                 {
    44.                     //Debug.Log("hit");
    45.                 }
    46.             })
    47.             .Schedule();
    48.     }
    49. }
    50.  
    51. [UpdateAfter(typeof(EndFramePhysicsSystem))]
    52. class Bar : SystemBase
    53. {
    54.     protected override void OnUpdate()
    55.     {
    56.         var s = World.GetExistingSystem<EndFramePhysicsSystem>();
    57.         Dependency = JobHandle.CombineDependencies(s.FinalJobHandle, Dependency);
    58.         var world = World.GetExistingSystem<BuildPhysicsWorld>().PhysicsWorld;
    59.        
    60.         Entities
    61.             .ForEach((BarComp c) =>
    62.             {
    63.                 var input = new PointDistanceInput
    64.                 {
    65.                     Filter = CollisionFilter.Default,
    66.                     MaxDistance = 100,
    67.                     Position = float3.zero
    68.                 };
    69.  
    70.                 var hits = new NativeList<DistanceHit>(Allocator.Temp);
    71.                 world.CalculateDistance(input, ref hits);
    72.                
    73.                 foreach (var hit in hits)
    74.                 {
    75.                     //Debug.Log("hit");
    76.                 }
    77.             })
    78.             .Schedule();
    79.     }
    80. }
    81.  
    82. struct FooComp : IComponentData
    83. {
    84. }
    85.  
    86. struct BarComp : IComponentData
    87. {
    88. }
    89.  
     
  2. Bas-Smit

    Bas-Smit

    Joined:
    Dec 23, 2012
    Posts:
    274