Destroyed Entity triggers ICollisionEventsJob

Hi
I am having a strange situation where i destroy an entity after it collides with the floor.

After the collision happens i destroy the entity(its removed in the entity debugger) but i still get ICollisionEventsJob collisions…

Am i missing something or is this a bug? the entity seems to still exist in the physics system somehow.
This happens every frame from now on and doesn’t stop until i exit the game

ps. I know i am having a collision by using Debug.Log inside ICollisionEventsJob

Thanks!

Hello, this sounds like a scheduling problem. Can I see the system/job scheduling code? Sounds like your events are fired at a wrong time and have stale data.

so are you saying i am destroying the entity at a wrong time? i will try dig up some code but the system is complicated so i am trying to figure out in principle what can go wrong

funny enough, there is a bit of mono code involved :slight_smile:

Yeah, if your event job runs at a wrong time, it could be too late to destroy the entity and next event job will also fire. Something along those lines.

its not running inside a job, it runs inside a system which runs after the physics stuff

But does it properly wait for the physics jobs to end?

[UpdateInGroup(typeof(FixedStepSimulationSystemGroup))]
[UpdateAfter(typeof(EndFramePhysicsSystem))]
[AlwaysUpdateSystem]

this should ensure it runs after the physics right?

I also have another strange bug… after i restart the scene within the game(restart level) and launch a projectile to shoot something the entire world hangs. it fails inside some job again and unity crashes, disabling burst and enabling leak detection crashes unity again and i can’t get any debug information at all
its turning into a nightmare

in the entity debugger again everything looks fine
I destroy the world on the mono event OnDestroy

i did some debug test and after spaming the mouse key to trigger explosions i get this error at some point

InvalidOperationException: 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 SphereCastJobForExplosion, which reads from the same Unity.Collections.NativeArray`1[Unity.Physics.CollisionFilter] (via SphereCastJobForExplosion.PhysicsCollisionWorld.Broadphase.m_StaticTree.BodyFilters). To guarantee safety, you must include Broadphase:PrepareStaticBodyDataJob as a dependenc
Unity.Jobs.LowLevel.Unsafe.JobsUtility.Schedule (Unity.Jobs.LowLevel.Unsafe.JobsUtility+JobScheduleParameters& parameters) (at <bad59441812943c7b8d5a5ba85795810>:0)
Unity.Jobs.IJobExtensions.Schedule[T] (T jobData, Unity.Jobs.JobHandle dependsOn) (at <bad59441812943c7b8d5a5ba85795810>:0)
ExplosionEventDataForSphereCast.Schedule (Unity.Physics.CollisionWorld& collisionWorld) (at Assets/Game/Scripts/Systems/ExplosionSystem.cs:476)
ExplosionSystem.OnUpdate () (at Assets/Game/Scripts/Systems/ExplosionSystem.cs:181)

I have this ExplosionSystem that runs AFTER EndFramePhysicsSystem and schedules some sphere cast JOBS

i do a Job.CompleteAll() at the end of the ExplosionSystem update function and handle all casts.

It seems when i started my sphere casts the physics system is not done??

You just schedule your system to run after EndFramePhysicsSystem, but you never tell it to wait for the last job from this system. You need to include EndFramePhysicsSystem.GetOutputDependency() as your input dependency. Also, make sure to add m_BuildPhysicsWorld.AddInputDependencyToComplete() and provide it your job’s dependency, so next physics step doesn’t run until your stuff is done.

since the ExplosionSystem system runs after endframephysicsSystem, where should i add this line of code?

AddInputDependencyToComplete → EndFramePhysicsSystem.GetOutputDependency()

do i need to write a new system that runs inbetween them to add this or is there some other way?

Ok so first you need 2 members in your system:

BuildPhysicsWorld m_BuildPhysicsWorld;
EndFramePhysicsSystem m_EndFramePhysicsSystem;

You fill them up in OnCreate() with GetOrCreateSystem().

OnUpdate:

JobHandle inputDeps = m_EndFramePhysicsSystem.GetOutputDependency(); // gets last job from end frame system

// do your work
// if you are scheduling jobs, include inputDeps
// if you are just executing work, call inputDeps.Complete() before doing so

// at the very end of OnUpdate(), and only if you were scheduling your own job and not executing work straight away
var handle = new MyJob().Schedule(inputDeps); // this is an example of how you scheduled your job
m_BuildPhysicsWorld.AddDependencyToComplete(handle); // this informs next physics step to wait for this to finish

I hope this makes it clearer.

1 Like

thanks very much peta, you are the best

1 Like

i still have a problem when i reload a scene using async unload/load or go to menu and then come back. I changed something in the project recently and i can’t figure out what causes this.
In the first time the game runs everything is perfect, when you reload it crashes.

However after i destroy the world, the entity debugger shows no entities in the world except the physics step and timer. There is nothing else… Almost immediately upon spawning a dynamic physics entity the game crashes with some burst error in the collision systems

This is the world destruction code that is called OnDestroy on the main scene

       if (PhysicsAssistant.EntityWorld != null && PhysicsAssistant.EntityWorld.IsCreated)
        {
            EntityQueryOptions defaultOptions = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled;
            if (!includePrefabs)
            {
                defaultOptions = EntityQueryOptions.IncludeDisabled;
            }

            var query = new EntityQueryDesc
            {
                Any = new ComponentType[] { typeof(SceneInstanceComponentData), typeof(CanBeForceExplodedComponentData), typeof(DestroyComponentData), typeof(GameObjectComponentData) },
        
                Options = defaultOptions,
            };

            EntityQuery entityGroup = PhysicsAssistant.EntityManagerRef.CreateEntityQuery(query);
            PhysicsAssistant.EntityManagerRef.DestroyEntity(entityGroup);
        }

Are there any hints as what might be going wrong?

Can you share the errors that you’re getting when the crash happens and the code that is calling Scene Load/Unload ?

i can’t… unity crashes completely if i disable burst and enable stack trace, i can’t get any debug info out of it
just this… and sometimes an extra error inside ICollisionEvent

System.NullReferenceException: Object reference not set to an instance of an object
This Exception was thrown from a job compiled with Burst, which has limited exception support. Turn off burst (Jobs -> Burst -> Enable Compilation) to inspect full exceptions & stacktraces

the load/unload has been working for long time, i have not done any changes to it.
i am suspecting something in the worlds or physics gets mixed up

private IEnumerator LoadGameRoutine(string[] sceneToUnload, string[] sceneToLoad, Action OnLoadCompleted, Action OnUnloadStarted)
    {
        if (OnUnloadStarted != null)
        {
            OnUnloadStarted();
        }

         LoadingScreen.SetActive(true);

        List<AsyncOperation> unloading = new List<AsyncOperation>();
        if (sceneToUnload != null)
        {
            for (int i = 0; i < sceneToUnload.Length; ++i)
            {
                AsyncOperation asyncUnload = UnityEngine.SceneManagement.SceneManager.UnloadSceneAsync(sceneToUnload[i]);
                unloading.Add(asyncUnload);
            }
            yield return null;
        }

        for (int i = 0; i < unloading.Count; ++i)
        {
            if (!unloading[i].isDone)
            {
                yield return null;
            }
        }


        if (sceneToLoad != null && sceneToLoad.Length > 0)
        {
            List<AsyncOperation> asyncLoads = new List<AsyncOperation>();
            for (int i = 0; i < sceneToLoad.Length; ++i)
            {
                AsyncOperation op = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync(sceneToLoad[i], UnityEngine.SceneManagement.LoadSceneMode.Additive);
                asyncLoads.Add(op);
                op.allowSceneActivation = false;
                while (op.progress < 0.9f)
                {
                    yield return null;
                }
            }

            for (int i = 0; i < asyncLoads.Count; ++i)
            {
                asyncLoads[i].allowSceneActivation = true;
                while (!asyncLoads[i].isDone)
                {
                    yield return null;
                }
            }
        }

        yield return null;
        Resources.UnloadUnusedAssets();
        yield return null;

        yield return null;
        yield return null;
        yield return null;

        LoadingScreen.SetActive(false);

        if (OnLoadCompleted != null)
        {
            OnLoadCompleted();
        }
    }

I have seen another variation of this bug… when i shoot a bomb in the floor, instead of exploding and it collides and slides forward…
basically the second time i run the game the collision worlds are strange

This seems very strange, could you provide me with a repro so I can figure out what is happening? Also, are you using UnityPhysics or HavokPhysics?

@argibaltzi did you try looking for hints about the crash in editor log (C:\Users<your user name>\AppData\Local\Unity\Editor\Editor.log)?

If jobs->leak detection->full stack traces is causing problems, you could try leaving it on/off and just disabling Burst.

its hard to get a repo, its complicated project, i would need to try and recreate on a clean project

@milos85miki
thanks for that suggestion, i looked into the editor log and i get this info after crash

Stacktrace:

  at <unknown> <0xffffffff>
  at (wrapper managed-to-native) Havok.Physics.Plugin.HP_SyncWorldIn (int,int,int,int,void*,int,Unity.Physics.MotionData*,int,Unity.Physics.MotionVelocity*,int,void*,int,int,bool) [0x00028] in <648764722fc64502a11bab9328e10a90>:0
  at Havok.Physics.HavokSimulation/SyncJob.Execute () [0x00045] in MyGame\Library\PackageCache\com.havok.physics@0.4.1-preview.2\Havok.Physics\HavokSimulation.cs:505
  at Unity.Jobs.IJobExtensions/JobStruct`1<Havok.Physics.HavokSimulation/SyncJob>.Execute (Havok.Physics.HavokSimulation/SyncJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int) [0x00008] in <e414e10bfe5f45729ff122f3359de21b>:0
  at (wrapper delegate-invoke) Unity.Jobs.IJobExtensions/JobStruct`1/ExecuteJobFunction<Havok.Physics.HavokSimulation/SyncJob>.invoke_void_T&_intptr_intptr_JobRanges&_int (Havok.Physics.HavokSimulation/SyncJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int) [0x00069] in <e414e10bfe5f45729ff122f3359de21b>:0
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void__this___intptr&_intptr_intptr_intptr&_int (object,intptr,intptr,intptr) [0x00039] in <e414e10bfe5f45729ff122f3359de21b>:0

and this

========== OUTPUTTING STACK TRACE ==================

0x00007FF94B192F3B (HavokNative) HP_UnlockPlugin
0x00007FF94AF11B02 (HavokNative) HP_SyncWorldIn
0x00000189AF24358A (Mono JIT Code) (wrapper managed-to-native) Havok.Physics.Plugin:HP_SyncWorldIn (int,int,int,int,void*,int,Unity.Physics.MotionData*,int,Unity.Physics.MotionVelocity*,int,void*,int,int,bool)
0x00000189AF24215B (Mono JIT Code) [MyGame\Library\PackageCache\com.havok.physics@0.4.1-preview.2\Havok.Physics\HavokSimulation.cs:505] Havok.Physics.HavokSimulation/SyncJob:Execute ()
0x00000189AF2406A3 (Mono JIT Code) Unity.Jobs.IJobExtensions/JobStruct`1<Havok.Physics.HavokSimulation/SyncJob>:Execute (Havok.Physics.HavokSimulation/SyncJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)
0x00000189AF240BE5 (Mono JIT Code) (wrapper delegate-invoke) Unity.Jobs.IJobExtensions/JobStruct`1/ExecuteJobFunction<Havok.Physics.HavokSimulation/SyncJob>:invoke_void_T&_intptr_intptr_JobRanges&_int (Havok.Physics.HavokSimulation/SyncJob&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int)
0x000001899E71E2EB (Mono JIT Code) (wrapper runtime-invoke) <Module>:runtime_invoke_void__this___intptr&_intptr_intptr_intptr&_int (object,intptr,intptr,intptr)
0x00007FF96281E0C0 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\mini\mini-runtime.c:2812] mono_jit_runtime_invoke
0x00007FF9627A2902 (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2921] do_runtime_invoke
0x00007FF9627AB95F (mono-2.0-bdwgc) [c:\build\output\unity-technologies\mono\mono\metadata\object.c:2968] mono_runtime_invoke
0x00007FF7535E5D94 (Unity) scripting_method_invoke
0x00007FF7535DE585 (Unity) ScriptingInvocation::Invoke
0x00007FF752DE411F (Unity) ExecuteJob
0x00007FF752DE508F (Unity) ForwardJobToManaged
0x00007FF752DC911B (Unity) JobQueue::Exec
0x00007FF752DC9A0A (Unity) JobQueue::ExecuteJobFromHighPriorityStack
0x00007FF752DCB719 (Unity) JobQueue::ProcessJobs
0x00007FF752DD213F (Unity) JobQueue::WorkLoop
0x00007FF7533FF7C5 (Unity) Thread::RunThreadWrapper
0x00007FF9FBAA7034 (KERNEL32) BaseThreadInitThunk
0x00007FF9FBCFD0D1 (ntdll) RtlUserThreadStart

========== END OF STACKTRACE ===========

Could you try using Unity Physics and see if it crashes, and post the log if it does?
Also, I would suggest completing physics systems before doing the unload of the scene (m_EndFramePhysicsSystem.GetOutputDependency().Complete()

It doesn’t crash with unity physics, i tried 10-15 times with burst on and off
everything works normal

I tried adding this code in the destroy world but it still crashes with havok on

  EndFramePhysicsSystem endFramePhysicsSystem = EntityWorld.GetExistingSystem<EndFramePhysicsSystem>();
endFramePhysicsSystem.GetOutputDependency().Complete();