Search Unity

InvalidOperationException: The previously scheduled job

Discussion in 'Entity Component System' started by echeg, May 22, 2019.

  1. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    Can anyone help me with error.

    Code (CSharp):
    1. InvalidOperationException: The previously scheduled job BoundingVolumeHierarchy:BuildFirstNLevelsJob writes to the NativeArray BuildFirstNLevelsJob.Ranges. You are trying to schedule a new job CollisionRaySystem:RayJob, which reads from the same NativeArray (via RayJob.Data.w.CollisionWorld.Broadphase.m_StaticTree.Ranges). To guarantee safety, you must include BoundingVolumeHierarchy:BuildFirstNLevelsJob as a dependency of the newly scheduled job.
    My system.
    Code (CSharp):
    1.     //*/
    2.     [UpdateAfter(typeof(BuildPhysicsWorld))]
    3.     public unsafe class CollisionRaySystem : JobComponentSystem
    4.     {
    5.         private BuildPhysicsWorld _physicsWorld;
    6.  
    7.         private BlobAssetReference<Collider> _sphere;
    8.         protected override void OnCreateManager()
    9.         {
    10.             _physicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
    11.  
    12.         }
    13.  
    14.         public void SetColFilter(CollisionFilter f)
    15.         {
    16.             _sphere = SphereCollider.Create(float3.zero, 0.25f, f);
    17.         }
    18.  
    19.         [BurstCompile]
    20.         private struct RayJob : IJobForEachWithEntity<SpellMayCollide, SpellVelocity, SpellPos, SpellCollision>
    21.         {
    22.             [ReadOnly] public PhysicsWorld w;
    23.             [ReadOnly] public BlobAssetReference<Collider> sphere;
    24.             public void Execute(
    25.                 Entity entity, int index,
    26.                 [ReadOnly] ref SpellMayCollide may,
    27.                 [ReadOnly] ref SpellVelocity vel,
    28.                 [ReadOnly] ref SpellPos pos,
    29.                 ref SpellCollision col
    30.                 )
    31.             {
    32.                 var colliderCastInput = new ColliderCastInput
    33.                 {
    34.                     Collider = (Collider*) sphere.GetUnsafePtr(),
    35.                     Orientation = quaternion.identity,
    36.                     Position = pos.Value,
    37.                     Direction = vel.Value
    38.                 };
    39.  
    40.                 if (w.CastCollider(colliderCastInput, out ColliderCastHit hit))
    41.                 {
    42.                     var hitBody = w.Bodies[hit.RigidBodyIndex];
    43.                     //col = new SpellCollision(entity, hitBody.Entity, hit);
    44.                     col.Spell = entity;
    45.                     col.Obstacle = hitBody.Entity;
    46.                     col.Hit = hit;
    47.                 }
    48.                 else
    49.                 {
    50.                     //col = new SpellCollision();
    51.                     col.Spell = Entity.Null;
    52.                     col.Obstacle = Entity.Null;
    53.                 }
    54.             }
    55.         }
    56.  
    57.         protected override JobHandle OnUpdate(JobHandle inputDeps)
    58.         {
    59.             return new RayJob
    60.             {
    61.                 w = _physicsWorld.PhysicsWorld,
    62.                 sphere = _sphere
    63.  
    64.             }.ScheduleSingle(this, inputDeps);
    65.         }
    66.     }
    Full stacktrace

    Code (CSharp):
    1. InvalidOperationException: The previously scheduled job BoundingVolumeHierarchy:BuildFirstNLevelsJob writes to the NativeArray BuildFirstNLevelsJob.Ranges. You are trying to schedule a new job CollisionRaySystem:RayJob, which reads from the same NativeArray (via RayJob.Data.w.CollisionWorld.Broadphase.m_StaticTree.Ranges). To guarantee safety, you must include BoundingVolumeHierarchy:BuildFirstNLevelsJob as a dependency of the newly scheduled job.
    2. Unity.Entities.JobForEachExtensions.Schedule (System.Void* fullData, Unity.Collections.NativeArray`1[T] prefilterData, System.Int32 unfilteredLength, System.Int32 innerloopBatchCount, System.Boolean isParallelFor, System.Boolean isFiltered, Unity.Entities.JobForEachExtensions+JobForEachCache& cache, System.Void* deferredCountData, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode) (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/IJobForEach.cs:364)
    3. Unity.Entities.JobForEachExtensions.ScheduleInternal_EDDDD[T] (T& jobData, Unity.Entities.ComponentSystemBase system, Unity.Entities.EntityQuery query, System.Int32 innerloopBatchCount, Unity.Jobs.JobHandle dependsOn, Unity.Jobs.LowLevel.Unsafe.ScheduleMode mode) (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/IJobForEach.gen.cs:1090)
    4. Unity.Entities.JobForEachExtensions.ScheduleSingle[T] (T jobData, Unity.Entities.ComponentSystemBase system, Unity.Jobs.JobHandle dependsOn) (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/IJobForEach.gen.cs:215)
    5. ArcanoidWars.Unity.ECS.CollisionRaySystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at Assets/Scripts/Logic/Systems/Collisions/CollisionRaySystem.cs:167)
    6. Unity.Entities.JobComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:696)
    7. Unity.Entities.ComponentSystemBase.Update () (at Library/PackageCache/com.unity.entities@0.0.12-preview.30/Unity.Entities/ComponentSystem.cs:166)
    8. ArcanoidWars.Unity.GameController.Execute () (at Assets/Scripts/Unity/GameController.cs:229)
    9. ArcanoidWars.Unity.GameController.Update () (at Assets/Scripts/Unity/GameController.cs:213)
    10.  
    Bug is inconsistent. Some times I have 1000+ frames with collisions before this happen
     
  2. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    You should not inject yourself after build world physics step. The exception is correctly telling you that you are creating a race condition.
     
  3. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    [UpdateAfter(typeof(BuildPhysicsWorld))] change to
    [UpdateBefore(typeof(BuildPhysicsWorld))] ?
     
  4. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    I can't remember the code (I'm on my phone), but you can also explicitly wait for the physics to complete if you need your systems to run after physics.
     
  5. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    May you provide solution?
     
  6. Shinyclef

    Shinyclef

    Joined:
    Nov 20, 2013
    Posts:
    505
    Sure. So I run a system immediately after physics has finished which relies on the colliders being ready, which is done the 'StepPhysicsWorld' system.

    So at the start of my system's 'OnUpdate' method, I do this (but without calling GetOrCreateSystem every time, instead just cache it):
    Code (CSharp):
    1. World.GetOrCreateSystem<StepPhysicsWorld>().FinalJobHandle.Complete();
    Your main thread will block while it waits for the system to complete.
     
    gaborkb likes this.
  7. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    or you just add
    FinalJobHandle
    as a dependency to your job:
    Code (CSharp):
    1. return job.Schedule(this, JobHandle.CombineDependencies(inputDeps, physicsWorld.FinalJobHandle);
     
  8. echeg

    echeg

    Joined:
    Aug 1, 2012
    Posts:
    90
    This strange I use rewrited Unity.physics. I remove StepPhysicsWorld and many other not used things... But increase speed 3x =)

    thx i think this help
     
    gaborkb and MNNoxMortem like this.
  9. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    I'm getting this also with my jobs being scheduled before physics. Combining dependencies won't work unless you also set FinalHandle after you combine/schedule. But it's readonly so can't do that.

    What I think would work is schedule my job after physics along with combine dependencies, as it would then complete before physics jobs completed. But holding off on that because there has to be a better way here, and I would need to make some non trivial updates to the order of things on my end.
     
  10. snacktime

    snacktime

    Joined:
    Apr 15, 2013
    Posts:
    3,356
    Ya Unity's own Ray tracer example runs after the physics systems and also does an immediate Complete because of this.

    So basically you have to run your system after the physics stuff and combine dependencies. Then from some other system that runs before physics complete your jobs.
     
  11. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    I have this error also :

    Code (CSharp):
    1. InvalidOperationException: The previously scheduled job RaycastJob reads from the NativeArray RaycastJob.World.Broadphase.m_StaticTree.Ranges. You are trying to schedule a new job BoundingVolumeHierarchy:BuildFirstNLevelsJob, which writes to the same NativeArray (via BuildFirstNLevelsJob.Ranges). To guarantee safety, you must include RaycastJob as a dependency of the newly scheduled job.
    But I run my system after physics and I give physic dependency but the system don't care :

    Code (CSharp):
    1.  
    2. [UpdateAfter(typeof(BuildPhysicsWorld))]
    3. public class InputSystem : JobComponentSystem
    4. {
    5.     /// <inheritdoc />
    6.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    7.     {
    8.         if (_pressed == false)
    9.             return inputDeps;
    10.  
    11.         _pressed = false;
    12.  
    13.         Debug.Log($"Pressed at {_mousePosition}");
    14.  
    15.         var ray = Camera.main.ScreenPointToRay(_mousePosition);
    16.  
    17.         _inputRaycast[0] = new RaycastInput
    18.         {
    19.             Start = ray.origin,
    20.             End   = ray.GetPoint(1024 * 2 * 2),
    21.             Filter = new CollisionFilter
    22.             {
    23.                 BelongsTo    = ~0u,
    24.                 CollidesWith = ~0u, // all 1s, so all layers, collide with everything
    25.                 GroupIndex   = 0
    26.             }
    27.         };
    28.  
    29.         var brush = new BrushSettings { Radius = 4.5F, HeightByEffect = 1.5F };
    30.  
    31.         var buildPhysicsWorld = World.Active.GetOrCreateSystem<BuildPhysicsWorld>();
    32.  
    33.         inputDeps =JobHandle.CombineDependencies(inputDeps, buildPhysicsWorld.FinalJobHandle);
    34.  
    35.         var physicsWorld =buildPhysicsWorld.PhysicsWorld;
    36.  
    37.         inputDeps = new RaycastJob { World = physicsWorld.CollisionWorld, Inputs = _inputRaycast, Results = _outputRaycastHit }.Schedule(1, 4, inputDeps);
    38.  
    39.         inputDeps = new ApplyBrushJob
    40.         {
    41.             RaycastHits = _outputRaycastHit, PhysicsWorld = physicsWorld, TilePositionCDEFERO = GetComponentDataFromEntity<TilePosition>(true), ClickPosition = _clickPosition
    42.         }.Schedule(inputDeps);
    43.  
    44.         inputDeps = new SelectionTileWithBrush
    45.         {
    46.             ClickPosition  = _clickPosition,
    47.             MapData        = World.GetOrCreateSystem<CreationTerrainRawSystem>().MapData,
    48.             BrushSettings  = brush,
    49.             SelectionQueue = _selectedEntitiesQueue.AsParallelWriter()
    50.         }.Schedule(this, inputDeps);
    51.  
    52.         return inputDeps;
    53.     }
    54. }
    I don't understand the logic here and I don't want to for completion of physics because it's against JobComponentSystem logic :/
     
  12. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    you need to depend on
    buildPhysicsWorld.FinalJobHandle
     
  13. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    Hi M_R

    Done at line 33
     
  14. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    where is
    BoundingVolumeHierarchy:BuildFirstNLevelsJob
    scheduled? you may want to add the dependency to that instead if avalable, or
     
  15. Sylmerria

    Sylmerria

    Joined:
    Jul 2, 2012
    Posts:
    369
    I don't know, It's internal physic logic.

    I want come after all that, it's why I have
    UpdateAfter([URL='http://www.google.com/search?q=typeof+msdn.microsoft.com']typeof[/URL](BuildPhysicsWorld))]

    and
    inputDeps =JobHandle.CombineDependencies(inputDeps, buildPhysicsWorld.FinalJobHandle);

    for this system
     
  16. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    you can read the Unity.Physics source code from the packages.

    I searched for that job, and it is scheduled in StepPhysicsWorld.

    you need to wait for that instead
     
    Sylmerria likes this.
  17. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    I've run into the same problem, but neither BuildPhysicsWorld.FinalJobHandle nor StepPhysicsWorld.
    FinalJobHandle as a dependency seems to solve it.

    Code (CSharp):
    1. InvalidOperationException: The previously scheduled job DrawingSpace:RaycastJob reads from the NativeArray RaycastJob.physicsWorld.CollisionWorld.Broadphase.m_StaticTree.Ranges. You are trying to schedule a new job BoundingVolumeHierarchy:BuildFirstNLevelsJob, which writes to the same NativeArray (via BuildFirstNLevelsJob.Ranges). To guarantee safety, you must include DrawingSpace:RaycastJob as a dependency of the newly scheduled job.
    Anyone has actually solved this? I am also doing some raycasts from a Job, in a similar way as the original post.

    Which is interesting - as this is the example for VehicleMechanicSystem in Unity.Physics examples:

    Code (CSharp):
    1. [UpdateAfter(typeof(BuildPhysicsWorld)), UpdateBefore(typeof(StepPhysicsWorld))]
    2.     public class VehicleMechanicsSystem : ComponentSystem
    and as pointed out
    The Unity.Physics example RayTracxerSystem only schedules itself as

    Code (CSharp):
    1.  
    2. [UpdateAfter(typeof(BuildPhysicsWorld))]
    3. public class RayTracerSystem : JobComponentSystem[code]
    4. However it uses the explicit Complete()
    5. [code=CSharp]
    6. for (int i = 0; i < m_Requests.Count; i++)
    7. {
    8.     JobHandle rcj = new RaycastJob
    9.     {
    10.         Results = m_Results[0].PixelData,
    11.         Request = m_Requests[0],
    12.         World = m_BuildPhysicsWorldSystem.PhysicsWorld.CollisionWorld,
    13.         NumDynamicBodies = m_BuildPhysicsWorldSystem.PhysicsWorld.NumDynamicBodies
    14.     }.Schedule(m_Results[0].PixelData.ForEachCount, 1, inputDeps);
    15.     rcj.Complete(); //<todo.eoin How can we properly wait on this task when reading results?
    16.     combinedJobs = JobHandle.CombineDependencies(combinedJobs, rcj);
    17. }
    Altough I am not sure why we need to combine dependencies to an already completed job?

    So what is actually the recommended way to register a custom system/job requiring Physics to be build without causing race conditions (and is it possible with jobs - as I am not aware of an equivalent of UpdateBefore for jobs).
     
    Last edited: Nov 13, 2019
  18. daschatten

    daschatten

    Joined:
    Jul 16, 2015
    Posts:
    208
    With entities 0.4 i used .WithReadOnly(collisionWorld) to get around this issue. After upgrading to 0.5 this doesn't work anymore as .WithReadOnly() requires the argument to have [NativeContainer] set.

    When using IJobForEachWithEntity i can still use [ReadOnly] on the CollisionWorld.

    Is there a way to set arguments to readonly in new ForEach if they don't have [NativeContainer] set? Or is there even a better way to query physics to prevent those dependency issues??
     
  19. Richay

    Richay

    Joined:
    Aug 5, 2013
    Posts:
    122
    Bump, because I would love an answer to this.

    I'm seeing this error.
    I've tried this, with no luck:
    Code (CSharp):
    1. var physicsWorldSystem = World.GetExistingSystem<BuildPhysicsWorld>();
    2. inputDeps = JobHandle.CombineDependencies(inputDeps, physicsWorldSystem.FinalJobHandle);
    3. inputDeps.Complete();
    My job is simply doing a raycast which is surely read-only, so I don't know why the error is even complaining about writing. I don't see a way to manually mark the raycast job as read-only.
     
  20. daschatten

    daschatten

    Joined:
    Jul 16, 2015
    Posts:
    208
    Here is a hacky solution for this issue, got it from someone on discord:

    * Update after physics:

    Code (CSharp):
    1. [UpdateAfter(typeof(BuildPhysicsWorld))]
    * Create a struct with CollisionWorld set to readonly:
    Code (CSharp):
    1. public struct CollisionWorldRo
    2. {
    3.     [ReadOnly] public CollisionWorld collisionWorld;
    4. }
    * Pass it to Entities.ForEach:

    Code (CSharp):
    1. var collisionWorldRo = new CollisionWorldRo{collisionWorld = _buildPhysicsWorld.PhysicsWorld.CollisionWorld};
    * Add physics as dependency:

    Code (CSharp):
    1. inputDeps = JobHandle.CombineDependencies(inputDeps, _buildPhysicsWorld.FinalJobHandle);
    That's it! Hopefully there is a cleaner solution in the future :)
     
    Last edited: Feb 18, 2020
    rz_0lento likes this.
  21. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    If you use new SystemBase from Entities 0.6, you can fix this part by putting this before your Entities.ForEach (SystemBase doesn't use inputDeps same way):
    Code (CSharp):
    1. Dependency = JobHandle.CombineDependencies(Dependency, _buildPhysicsWorld.FinalJobHandle);
     
  22. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    @rz_0lento, @daschatten - seems not to work with Entities 0.10 anymore

    Code (CSharp):
    1. [UpdateAfter(typeof(StepPhysicsWorld)),UpdateAfter(typeof(BuildPhysicsWorld))]
    2.         public class RaycastSystem : SystemBase
    3.         {      
    4.             protected override void OnUpdate()
    5.             {
    6.                 var buildPhysicsWorld = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<BuildPhysicsWorld>();
    7.                 Dependency = JobHandle.CombineDependencies(Dependency, buildPhysicsWorld.FinalJobHandle);
    8.            
    9.                 var physicsWorld = buildPhysicsWorld.PhysicsWorld;
    10.                 Entities.WithName(nameof(RaycastSystem))
    11.                         .ForEach((ref RaycastRequest request) =>
    12.                                  {
    13.                                      if (request.Completed)
    14.                                          return;
    15.                                      if (!request.ConsideredBeforeBuildPhysicsWorld)
    16.                                          return;
    17.                                      request.Hit           = physicsWorld.CastRay(request.RaycastInput, out Unity.Physics.RaycastHit closestHit);
    18.                                      request.RaycastResult = closestHit;
    19.                                      request.Completed     = true;
    20.                                  })
    21.                         .ScheduleParallel();
    22.             }
    23.         }
    Does throw

    Code (CSharp):
    1. [Exception] InvalidOperationException: The previously scheduled job ExportPhysicsWorld:ExportDynamicBodiesJob reads from the Unity.Collections.NativeArray`1[Unity.Physics.MotionData] ExportDynamicBodiesJob.JobData.MotionDatas. You are trying to schedule a new job RaycastSystem:<>c__DisplayClass_RaycastSystem, which writes to the same Unity.Collections.NativeArray`1[Unity.Physics.MotionData] (via <>c__DisplayClass_RaycastSystem.JobData.physicsWorld.DynamicsWorld.m_MotionDatas). To guarantee safety, you must include ExportPhysicsWorld:ExportDynam
    2. JobChunkExtensions.ScheduleInternal[T]()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/IJobChunk.cs:216
    3. 214:               prefilterHandle.Complete();
    4. 215:               prefilterData.Dispose();
    5. -->216:               throw e;
    6. 217:           }
    7. 218:   #endif
    8.  
    9. JobChunkExtensions.ScheduleParallel[T]()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/IJobChunk.cs:128
    10. 126:       where T : struct, IJobChunk
    11. 127:   {
    12. -->128:       return ScheduleInternal(ref jobData, query, dependsOn, ScheduleMode.Batched, true);
    13. 129:   }
    14.  
    15. ProjectionSystem+RaycastSystem.OnUpdate()    Assets/Scripts/Controller/Measurements/ProjectionSystem.cs:77
    16. 76:   var physicsWorld = buildPhysicsWorld.PhysicsWorld;
    17. -->77:   Entities.WithName(nameof(RaycastSystem))
    18. 78:           .ForEach((ref RaycastRequest request) =>
    19. 79:                    {
    20.  
    21. SystemBase.Update()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/SystemBase.cs:414
    22. 412:   #endif
    23. -->414:                           throw;
    24. 415:                       }
    25.  
    26. ComponentSystemGroup.UpdateAllSystems()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:240
    27. 238:   try
    28. 239:   {
    29. -->240:       sys.Update();
    30. 241:   }
    31. 242:   catch (Exception e)
    32.  
    33. Debug.LogException()
    34.  
    35. Debug.LogException()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/Stubs/Unity/Debug.cs:19
    36. 17:       UnityEngine.Debug.Log(message);
    37. 18:   public static void LogException(Exception exception) =>
    38. -->19:       UnityEngine.Debug.LogException(exception);
    39. 21:   #if !NET_DOTS
    40.  
    41. ComponentSystemGroup.UpdateAllSystems()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:244
    42. 242:                   catch (Exception e)
    43. 243:                   {
    44. -->244:                       Debug.LogException(e);
    45. 245:   #if UNITY_DOTSPLAYER
    46. 246:                       // When in a DOTS Runtime build, throw this upstream -- continuing after silently eating an exception
    47.  
    48. ComponentSystemGroup.OnUpdate()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:219
    49. 217:   if (UpdateCallback == null)
    50. 218:   {
    51. -->219:       UpdateAllSystems();
    52. 220:   }
    53. 221:   else
    54.  
    55. ComponentSystem.Update()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystem.cs:109
    56. 107:   try
    57. 108:   {
    58. -->109:       OnUpdate();
    59. 110:   }
    60. 111:   finally
    61.  
    62. Unity.Entities.DummyDelegateWrapper.TriggerUpdate()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ScriptBehaviourUpdateOrder.cs:196
    63. 194:       public void TriggerUpdate()
    64. 195:       {
    65. -->196:           m_System.Update();
    66. 197:       }
    67. 198:   }
    68.  
    and

    Code (CSharp):
    1. public struct CollisionWorldRo
    2.         {
    3.             [ReadOnly] public CollisionWorld collisionWorld;
    4.         }
    5.  
    6.  
    7.         // Always use SystemBase: https://forum.unity.com/threads/is-there-any-difference-between-systembase-jobcomponentsystem-and-componentsystem-anymore.892978/
    8.         [UpdateAfter(typeof(BuildPhysicsWorld))]
    9.         public class RaycastSystem : SystemBase
    10.         {        
    11.             protected override void OnUpdate()
    12.             {
    13.                 var buildPhysicsWorld = World.DefaultGameObjectInjectionWorld.GetOrCreateSystem<BuildPhysicsWorld>();
    14.                 var collisionWorldRo = new CollisionWorldRo{collisionWorld = buildPhysicsWorld.PhysicsWorld.CollisionWorld};
    15.  
    16.                 Dependency = JobHandle.CombineDependencies(Dependency, buildPhysicsWorld.FinalJobHandle);
    17.            
    18.                 var physicsWorld = buildPhysicsWorld.PhysicsWorld;
    19.                 Entities.WithName(nameof(RaycastSystem))
    20.                         .ForEach((ref RaycastRequest request) =>
    21.                                  {
    22.                                      if (request.Completed)
    23.                                          return;
    24.                                      if (!request.ConsideredBeforeBuildPhysicsWorld)
    25.                                          return;
    26.                                      request.Hit           = collisionWorldRo.collisionWorld.CastRay(request.RaycastInput, out Unity.Physics.RaycastHit closestHit);
    27.                                      request.RaycastResult = closestHit;
    28.                                      request.Completed     = true;
    29.                                  })
    30.                         .ScheduleParallel();
    31.             }
    32.         }
    does throw

    Code (CSharp):
    1. [Exception] InvalidOperationException: The previously scheduled job RaycastSystem:<>c__DisplayClass_RaycastSystem reads from the Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] <>c__DisplayClass_RaycastSystem.JobData.collisionWorldRo.collisionWorld.Broadphase.m_StaticTree.BodyFilters. You are trying to schedule a new job Broadphase:PrepareStaticBodyDataJob, which writes to the same Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] (via PrepareStaticBodyDataJob.FiltersOut). To guarantee safety, you must include Raycas
    2. JobsUtility.ScheduleParallelForDeferArraySize()    <fdd4f5823e2a41e8be8d5dcbd0bfd5b1>:0
    3.  
    4. IJobParallelForDeferExtensions.Schedule[T]()    Library/PackageCache/com.unity.jobs@0.2.9-preview.15/Unity.Jobs/IJobParallelForDefer.cs:111
    5. 110:       var forEachListPtr = (byte*)forEachCount - sizeof(void*);
    6. -->111:       return JobsUtility.ScheduleParallelForDeferArraySize(ref scheduleParams, innerloopBatchCount,
    7. 112:           forEachListPtr, null);
    8. 113:   }
    9.  
    10. IJobParallelForDeferExtensionsPhysics.ScheduleUnsafeIndex0[T]()    Library/PackageCache/com.unity.physics@0.3.2-preview/Unity.Physics/Base/Jobs/IJobParallelForDeferExtensionsPhysics.cs:11
    11. 9:           where T : struct, IJobParallelForDefer
    12. 10:       {
    13. -->11:           return IJobParallelForDeferExtensions.Schedule(jobData, (int*)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(forEachCount), innerloopBatchCount, dependsOn);
    14. 12:       }
    15. 13:   }
    16.  
    17. Broadphase.ScheduleStaticTreeBuildJobs()    Library/PackageCache/com.unity.physics@0.3.2-preview/Unity.Physics/Collision/World/Broadphase.cs:186
    18. 184:   }.Schedule(inputDeps);
    19. -->186:   var staticBodyDataJobHandle = new PrepareStaticBodyDataJob
    20. 187:   {
    21. 188:       RigidBodies = world.StaticBodies,
    22.  
    23. Broadphase.ScheduleBuildJobs()    Library/PackageCache/com.unity.physics@0.3.2-preview/Unity.Physics/Collision/World/Broadphase.cs:157
    24. 155:   else
    25. 156:   {
    26. -->157:       return JobHandle.CombineDependencies(
    27. 158:           ScheduleStaticTreeBuildJobs(ref world, threadCountHint, buildStaticTree, inputDeps),
    28. 159:           ScheduleDynamicTreeBuildJobs(ref world, timeStep, gravity, threadCountHint, inputDeps));
    29.  
    30. CollisionWorld.ScheduleBuildBroadphaseJobs()    Library/PackageCache/com.unity.physics@0.3.2-preview/Unity.Physics/Collision/World/CollisionWorld.cs:82
    31. 80:   public JobHandle ScheduleBuildBroadphaseJobs(ref PhysicsWorld world, float timeStep, float3 gravity, NativeArray<int> buildStaticTree, JobHandle inputDeps, int threadCountHint = 0)
    32. 81:   {
    33. -->82:       return Broadphase.ScheduleBuildJobs(ref world, timeStep, gravity, buildStaticTree, inputDeps, threadCountHint);
    34. 83:   }
    35.  
    36. BuildPhysicsWorld.OnUpdate()    Library/PackageCache/com.unity.physics@0.3.2-preview/Unity.Physics/ECS/Systems/BuildPhysicsWorld.cs:241
    37. 239:   }
    38. -->241:   JobHandle buildBroadphaseHandle = PhysicsWorld.CollisionWorld.ScheduleBuildBroadphaseJobs(
    39. 242:       ref PhysicsWorld, timeStep, stepComponent.Gravity,
    40. 243:       haveStaticBodiesChanged, handle, stepComponent.ThreadCountHint);
    41.  
    42. JobComponentSystem.Update()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/JobComponentSystem.cs:141
    43. 140:       AfterOnUpdate(outputJob, false);
    44. -->141:       throw;
    45. 142:   }
    46.  
    47. ComponentSystemGroup.UpdateAllSystems()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:240
    48. 238:   try
    49. 239:   {
    50. -->240:       sys.Update();
    51. 241:   }
    52. 242:   catch (Exception e)
    53.  
    54. Debug.LogException()
    55.  
    56. Debug.LogException()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/Stubs/Unity/Debug.cs:19
    57. 17:       UnityEngine.Debug.Log(message);
    58. 18:   public static void LogException(Exception exception) =>
    59. -->19:       UnityEngine.Debug.LogException(exception);
    60. 21:   #if !NET_DOTS
    61.  
    62. ComponentSystemGroup.UpdateAllSystems()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:244
    63. 242:                   catch (Exception e)
    64. 243:                   {
    65. -->244:                       Debug.LogException(e);
    66. 245:   #if UNITY_DOTSPLAYER
    67. 246:                       // When in a DOTS Runtime build, throw this upstream -- continuing after silently eating an exception
    68.  
    69. ComponentSystemGroup.OnUpdate()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystemGroup.cs:219
    70. 217:   if (UpdateCallback == null)
    71. 218:   {
    72. -->219:       UpdateAllSystems();
    73. 220:   }
    74. 221:   else
    75.  
    76. ComponentSystem.Update()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ComponentSystem.cs:109
    77. 107:   try
    78. 108:   {
    79. -->109:       OnUpdate();
    80. 110:   }
    81. 111:   finally
    82.  
    83. Unity.Entities.DummyDelegateWrapper.TriggerUpdate()    Library/PackageCache/com.unity.entities@0.10.0-preview.6/Unity.Entities/ScriptBehaviourUpdateOrder.cs:196
    84. 194:       public void TriggerUpdate()
    85. 195:       {
    86. -->196:           m_System.Update();
    87. 197:       }
    88. 198:   }
    89.  
     
    Last edited: Jun 1, 2020
  23. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    I tried to copy the RaycastWithCustomCollectorSystem from UnityPhysicsSamples

    Code (CSharp):
    1. [UpdateAfter(typeof(EndFramePhysicsSystem))]
    2. public class RaycastWithCustomCollectorSystem : SystemBase
    3. {
    4.     BuildPhysicsWorld m_BuildPhysicsWorld;
    5.     EndFramePhysicsSystem m_EndFramePhysicsSystem;
    6.     EntityCommandBufferSystem m_EntityCommandBufferSystem;
    7.  
    8.     protected override void OnCreate()
    9.     {
    10.         m_BuildPhysicsWorld = World.GetOrCreateSystem<BuildPhysicsWorld>();
    11.         m_EndFramePhysicsSystem = World.GetOrCreateSystem<EndFramePhysicsSystem>();
    12.         m_EntityCommandBufferSystem = World.GetOrCreateSystem<EntityCommandBufferSystem>();
    13.     }
    14.  
    15.     protected override void OnUpdate()
    16.     {
    17.         CollisionWorld collisionWorld = m_BuildPhysicsWorld.PhysicsWorld.CollisionWorld;
    18.         EntityCommandBuffer commandBuffer = m_EntityCommandBufferSystem.CreateCommandBuffer();
    19.         Dependency = JobHandle.CombineDependencies(Dependency, m_EndFramePhysicsSystem.FinalJobHandle);
    20.  
    21.         Entities
    22.             .WithName("RaycastWithCustomCollector")
    23.             .WithBurst()
    24.             .ForEach((Entity entity, ref Translation position, ref Rotation rotation, ref VisualizedRaycast visualizedRaycast) =>
    25.         {
    26.             var raycastLength = visualizedRaycast.RayLength;
    27.          
    28.             // Perform the Raycast
    29.             var raycastInput = new RaycastInput
    30.             {
    31.                 Start = position.Value,
    32.                 End = position.Value + (math.forward(rotation.Value) * visualizedRaycast.RayLength),
    33.                 Filter = CollisionFilter.Default
    34.             };
    35.  
    36.             var collector = new IgnoreTransparentClosestHitCollector(collisionWorld);
    37.  
    38.             collisionWorld.CastRay(raycastInput, ref collector);
    39.  
    40.             var hit = collector.ClosestHit;
    41.             var hitDistance = raycastLength * hit.Fraction;
    42.  
    43.             // position the entities and scale based on the ray length and hit distance
    44.             // visualization elements are scaled along the z-axis aka math.forward
    45.             var newFullRayPosition = new float3(0, 0, raycastLength * 0.5f);
    46.             var newFullRayScale = new float3(1f, 1f, raycastLength);
    47.             var newHitPosition = new float3(0, 0, hitDistance);
    48.             var newHitRayPosition = new float3(0, 0, hitDistance * 0.5f);
    49.             var newHitRayScale = new float3(1f, 1f, raycastLength * hit.Fraction);
    50.  
    51.             commandBuffer.SetComponent(visualizedRaycast.HitPositionEntity, new Translation { Value = newHitPosition });
    52.             commandBuffer.SetComponent(visualizedRaycast.HitRayEntity, new Translation { Value = newHitRayPosition });
    53.             commandBuffer.SetComponent(visualizedRaycast.HitRayEntity, new NonUniformScale { Value = newHitRayScale });
    54.             commandBuffer.SetComponent(visualizedRaycast.FullRayEntity, new Translation { Value = newFullRayPosition });
    55.             commandBuffer.SetComponent(visualizedRaycast.FullRayEntity, new NonUniformScale { Value = newFullRayScale });
    56.         }).Schedule();
    57.  
    58.         m_EntityCommandBufferSystem.AddJobHandleForProducer(Dependency);
    59.     }
    And replaced the actual content and removed the EntityCommandBuffer (as I don't do structural changes) and without having an explicit Dependency.Complete() it causes the InvalidOperationException - where a Complete() obviously causes a lock.

    Code (CSharp):
    1. [UpdateAfter(typeof(BuildPhysicsWorld))]
    2.         public class RaycastSystem : SystemBase
    3.         {
    4.             private BuildPhysicsWorld     buildPhysicsWorld;
    5.             private EndFramePhysicsSystem endFramePhysicsSystem;
    6.  
    7.             protected override void OnCreate()
    8.             {
    9.                 buildPhysicsWorld     = World.GetOrCreateSystem<BuildPhysicsWorld>();
    10.                 endFramePhysicsSystem = World.GetOrCreateSystem<EndFramePhysicsSystem>();
    11.             }
    12.  
    13.             protected override void OnUpdate()
    14.             {
    15.                 CollisionWorld collisionWorld = buildPhysicsWorld.PhysicsWorld.CollisionWorld;
    16.                 Dependency = JobHandle.CombineDependencies(Dependency, endFramePhysicsSystem.FinalJobHandle);
    17.  
    18.                 Dependency = Entities.WithName(nameof(RaycastSystem))
    19.                                      .ForEach((ref RaycastRequest request) =>
    20.                                               {
    21.                                                   if (request.Completed)
    22.                                                       return;
    23.                                                   if (!request.ConsideredBeforeBuildPhysicsWorld)
    24.                                                       return;
    25.  
    26.                                                   request.Hit           = collisionWorld.CastRay(request.RaycastInput, out Unity.Physics.RaycastHit closestHit);
    27.                                                   request.RaycastResult = closestHit;
    28.                                                   request.Completed     = true;
    29.                                               })
    30.                                      .Schedule(Dependency);
    31.                 Dependency.Complete(); // <- Required or will cause InvalidOperationException - see above.
    32.             }
    33.         }
    As the example does not require the explicit Dependency.Complete() does anybody know why I might require it? I just could imagine, although the System might start after BuildPhysicsWorld there is no guarantee it doesn't run into the next cycle of BuildPhysicsWorld, and this causing them to interact badly.
     
    Last edited: Jun 3, 2020
    Sky_Higher likes this.
  24. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    Could someone confirm, that with the latest version of Unity.Physics/Entities/Jobs it is actually not possible to have long running Raycast jobs against a PhysicsWorld/CollisionWorld?

    In short the only way I was able to solve all of the above was to:
    * Schedule after BuildPhysicsWorld and StepPhysicsWorld
    * Schedule before EndFramePhysicsSystem (which is more or less almost equivalent calling .Complete() as there is not much time buffer between BuildPhysicsWorld and EndFramePhysicsSystem....)

    This resolves the raycasts successfully without throwing Exceptions, but it completly defeats my initial goal. I wanted to schedule a raycast at Time t and resolve it (against the state of the PhysicsWorld of that Time t) at a later point Time t+x

    In the past I have run into warnings for NativeArrays allocated over multiple (4) frames, but this time now I was not able to get it to work without being very explicit about the system before and the system afterwards.

    Okay, to be fair, SystemBase really is designed to run every single frame and complete within that frame, but could the same achieved by managing the jobs manually? What difference would I need to be careful with when moving from SystemBase to IJob?
     
  25. MNNoxMortem

    MNNoxMortem

    Joined:
    Sep 11, 2016
    Posts:
    723
    I don't get it. Everytime I think I really understand it, something new pops up. This is the system I have copied from one Project where it works to another and there it breaks with this error again

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Jobs;
    3. using Unity.Physics.Systems;
    4.  
    5. // Always use SystemBase: https://forum.unity.com/threads/is-there-any-difference-between-systembase-jobcomponentsystem-and-componentsystem-anymore.892978/
    6. [UpdateAfter(typeof(EndFramePhysicsSystem))]
    7. [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    8. public class RaycastSystem : SystemBase
    9. {
    10.     private BuildPhysicsWorld     buildPhysicsWorld;
    11.     private StepPhysicsWorld      stepPhysicsWorld;
    12.     private EntityQuery           query;
    13.     private EndFramePhysicsSystem endFramePhysicsSystem;
    14.  
    15.     protected override void OnCreate()
    16.     {
    17.         stepPhysicsWorld      = World.GetOrCreateSystem<StepPhysicsWorld>();
    18.         buildPhysicsWorld     = World.GetOrCreateSystem<BuildPhysicsWorld>();
    19.         endFramePhysicsSystem = World.GetExistingSystem<EndFramePhysicsSystem>();
    20.     }
    21.  
    22.     protected override void OnUpdate()
    23.     {
    24.         // ref PhysicsWorld physicsWorld = ref  this.buildPhysicsWorld.PhysicsWorld;
    25.         //var collisionWorld =  buildPhysicsWorld.PhysicsWorld.CollisionWorld;
    26.         ref var physicsWorld = ref buildPhysicsWorld.PhysicsWorld;
    27.         Dependency = JobHandle.CombineDependencies(Dependency, buildPhysicsWorld.GetOutputDependency(), stepPhysicsWorld.GetOutputDependency());
    28.         int            count          = query.CalculateEntityCount();
    29.         var collisionWorld = physicsWorld.CollisionWorld;
    30.  
    31.         Dependency = Entities.WithName(nameof(RaycastSystem))
    32.                              //.WithReadOnly(collisionWorld)
    33.                              .ForEach((ref RaycastRequest request) =>
    34.                                       {
    35.  
    36.  
    37.                                           if (request.Completed)
    38.                                               return;
    39.                                            request.Hit           = collisionWorld.CastRay(request.RaycastInput, out var closestHit);
    40.                                            request.RaycastResult = closestHit;
    41.                                            request.Completed     = true;
    42.                                           //Debug.Log($"Request hit: {closestHit.Fraction} {closestHit.Entity} {closestHit.Position}");
    43.                                       })
    44.                             .WithStoreEntityQueryInField(ref query)
    45.                             .Schedule(Dependency);
    46.         endFramePhysicsSystem.AddInputDependency(Dependency);
    47.        
    48.     }
    49. }
    Now I have two projects and in one it works, and in the other unity complains. Same verison of Jobs, Entities and Collections.
     
    adammpolak likes this.
  26. adammpolak

    adammpolak

    Joined:
    Sep 9, 2018
    Posts:
    450
    I can't make heads or tails of what is going on when trying to implement player scoring using collisions from Unity Physics.

    -I took the sample trigger physics example from the github

    - altered the "collision entrance section" so that I grab the ghostOwnerComponent (networkId) and compare it to a NativeArray of PlayerScore networkIds

    - If they match, I ++ the player score.

    - I grab the PlayerScore with:

    var playerScores = m_PlayerScores.ToComponentDataArrayAsync<PlayerScore>(Allocator.TempJob, out playerScoreDep);


    - At the end of the OnUpdate I have
    Dependency = JobHandle.CombineDependencies(Dependency, playerScoreDep);
    m_CommandBufferSystem.AddJobHandleForProducer(Dependency);
    playerScores.Dispose();


    For some reason, the change in player score does not "stick". I Debug.Log the playerScore every time I reach for it, and it is always 0.

    Code (CSharp):
    1.                     //this is what happens when the bullet enters
    2.                     else if (triggerEvent.State == EventOverlapState.Enter)
    3.                     {
    4.  
    5.                         // //we find the bullets Owner
    6.                         var bulletsPlayerNetworkId = ghostOwner[e].NetworkId;
    7.                         int pointsToAdd = 0;
    8.                         if (EntityManager.HasComponent<AsteroidTag>(otherEntity))
    9.                         {
    10.                             pointsToAdd += 1;
    11.                         }
    12.                         for (int j = 0; j < playerScores.Length; j++)
    13.                         {
    14.                             //if the playerScore's owner is the same as the bullet's owner, add to the score
    15.                             if(playerScores[j].networkId == bulletsPlayerNetworkId)
    16.                             {
    17.                                 Debug.Log("points to add: " + pointsToAdd);
    18.                                 Debug.Log("Current score before addition: " + playerScores[j].currentScore);
    19.                                 var newPlayerScore = new PlayerScore{
    20.                                     networkId = playerScores[j].networkId,
    21.                                     playerName = playerScores[j].playerName,
    22.                                     currentScore = playerScores[j].currentScore + pointsToAdd,
    23.                                     highScore = 0
    24.                                     };
    25.                                 playerScores[j] = newPlayerScore;
    26.                                 Debug.Log("what seems to be the final result score: " + playerScores[j].currentScore);
    27.                             }
    28.                         }
    29. ...
    30. .Run();
    31. Dependency = JobHandle.CombineDependencies(Dependency, playerScoreDep);
    32. m_CommandBufferSystem.AddJobHandleForProducer(Dependency);
    33. playerScores.Dispose();
    34.  
    the "Current score before addition: " always returns 0.

    Is it because the NativeArray isn't "linked" to the entity?
    Am I just changing the value in a random array?
    Do I have to somehow reference the actual entity with the component and then update it with the new value?
    Is it because I am in FixedStepSimulationSystemGroup and that some how doesn't count?
    Is it because I playerScores.Dispose() too early somehow?
     
  27. nanobot_games

    nanobot_games

    Joined:
    Jul 22, 2019
    Posts:
    10
    I believe when you modify the value of an element in the array you create using ToComponentDataArrayAsync, it does not modify the value on the entity. When you debug is newPlayerScore always 0? Instead of using ToComponentDataArrayAsync, are you able to use ComponentTypeHandle<PlayerScore> or GetComponentDataFromEntity<PlayerScore>? Not sure what version of Entities you are using - but I have always found the documentation here to be very useful if you haven't looked through it already
     
  28. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    If you want to return modifications from
    ToComponentDataArrayAsync
    back - you should use this with
    CopyFromComponentDataArray(Async)
     
    adammpolak likes this.
  29. Campi

    Campi

    Joined:
    Feb 25, 2013
    Posts:
    9
    After long reading searching for a solution for a similar issue:
    Code (CSharp):
    1. InvalidOperationException: The previously scheduled job LocomotionAbilitySystem:Locomotion_Ability_Update reads from the Unity.Collections.NativeHashMap`2[Unity.Entities.Entity,System.Int32] Locomotion_Ability_Update.JobData.physicsWorld.CollisionWorld.EntityBodyIndexMap. You must call JobHandle.Complete() on the job LocomotionAbilitySystem:Locomotion_Ability_Update, before you can write to the Unity.Collections.NativeHashMap`2[Unity.Entities.Entity,System.Int32] safely.
    It finally works with this structure: (using SystemBase base class)
    Code (CSharp):
    1.            
    2. Dependency = JobHandle.CombineDependencies(Dependency, buildPhysicsWorld.GetOutputDependency());
    3. var physicsWorld = buildPhysicsWorld.PhysicsWorld;
    4.  
    5. Dependency = Entities.WithReadOnly(physicsWorld)
    6.                      .ForEach((....)=>
    7.                      {
    8.                      }).ScheduleParallel(Dependency);
    9.  buildPhysicsWorld.AddInputDependencyToComplete(Dependency);
    10.  
    And my system is updated in the following group/order:

    Code (CSharp):
    1.     [UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
    2.     [UpdateAfter(typeof(ExportPhysicsWorld))]
    3.     [UpdateBefore(typeof(EndFramePhysicsSystem))]
    I hope this helps
     
    MNNoxMortem likes this.
  30. adammpolak

    adammpolak

    Joined:
    Sep 9, 2018
    Posts:
    450
    @Campi this is great thank you.

    For some reason when working with Physics it is hard to get dependencies/update in/after correct and I feel like I have a good grip on things.

    Hopefully, there is some kind of visual aid that Unity developed to help figure these things out. I sketch out diagrams but I guess my assumptions are wrong.
     
    MNNoxMortem likes this.
  31. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    I too tried to use the physics sample from github and got the dreaded error: "The previously scheduled job Broadphase.PrepareStaticBodyDataJob writes to the Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] PrepareStaticBodyDataJob.FiltersOut. You are trying to schedule a new job OnUpdate_LambdaJob0, which reads from the same Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] (via OnUpdate_LambdaJob0.JobData.world.Broadphase.m_StaticTree.BodyFilters). To guarantee safety, you must include Broadphase.PrepareStaticBodyDataJob as a dependency of the newly scheduled job."

    All I did was copy the file DynamicBufferTriggerEventAuthoring.cs into my project... I didn't modify it at all. After that, two of my systems - both systems have calls to world.OverlapAabb() started spitting out that monster error. Commenting out the contents of DynamicBufferTriggerEventAuthoring makes the other two overlap-aabb scripts work again, so it's merely the act of adding the file that is causing the other two systems to vomit.

    What I ended up doing to fix it was adding

    Code (CSharp):
    1. using Unity.Jobs
    2. .....
    3. OnUpdate() {
    4.     Dependency = JobHandle.CombineDependencies(Dependency, m_world.GetOutputDependency());
    5.    CollisionWorld world = m_world.PhysicsWorld.CollisionWorld;
    6.    Entities.ForEach(...) => {  ...call to world.OverlapAabb() here... }).WithReadOnly(world).ScheduleParallel();
    7.    m_world.AddInputDependencyToComplete(Dependency);
    8. }
    I think the trick was the CombineDependencies() bit because everything else I had there already. I do not have any specifiers for update-in-group or update-after etc... so those two overlap-aabb systems are just running in the normal simulation group. I'm not sure if I'm supposed to put them in the fixed-step sim group or something, but they seem to be working fine.... they might be a frame behind or something but it's not noticeable.

    I find it disturbing that the act of adding a completely independent system to my project can cause two previously working unrelated scripts to start failing with a cryptic error. If anyone from Unity is listening in... I'm a long time coder but a rookie game dev so I'm not an expert in gaming physics engines.... and to be honest I have more pressing things on my plate than to understand all the internal details of how a physics engine works. I find the ordering of these physics systems and dependency chain really confusing.
     
    Last edited: Nov 26, 2021
    MehO likes this.
  32. unity_T_sIWDQP7tpPpA

    unity_T_sIWDQP7tpPpA

    Joined:
    Aug 30, 2021
    Posts:
    1
    Thanks @lclemens !

    Adding
    Dependency = JobHandle.CombineDependencies(Dependency, m_world.GetOutputDependency());
    and
    m_world.AddInputDependencyToComplete(Dependency);
    lines (as in your snippet) helped in my case!
     
    lclemens likes this.
  33. nikk98

    nikk98

    Joined:
    Mar 8, 2021
    Posts:
    43
    It's much easier on Entities 0.51.

    Just add:

    Code (CSharp):
    1.        
    2. protected override void OnCreate() {
    3.             _buildPhysicsWorld = World.DefaultGameObjectInjectionWorld.GetExistingSystem<BuildPhysicsWorld>();
    4.         }
    5.  
    6.         protected override void OnStartRunning() {
    7.             _buildPhysicsWorld.RegisterPhysicsRuntimeSystemReadOnly();
    8.         }
    9.  
    And the error goes away.

    My system runs with:

    [UpdateInGroup(typeof(PresentationSystemGroup))],

    and is starting an IJobParallelFor job. I don't think either is relevant though.
     
  34. lclemens

    lclemens

    Joined:
    Feb 15, 2020
    Posts:
    761
    In 0.50+ There were a couple of situations where RegisterPhysicsRuntimeSystemReadOnly() wasn't enough and I had to still use dependency combinations. It mainly had to do with systems where I was using ToComponentDataArray().
     
  35. nikk98

    nikk98

    Joined:
    Mar 8, 2021
    Posts:
    43
    Yeah I'm getting this now too - but only occasionally which is confusing. The raycastinf system is triggered by user action, but the raycast should always be happening at the same system group in the frame. I don't think it's happening on Android though.

    It happens occasionally on the first time the system that does raycast runs. Im spawning some objects with colliders, it looks like a racing condition.
    The tips from this thread were not working for me.