What is the proper way to manipulate entities or components in non ECS context like MonoBehaviour?

I’m destroying some entities via a MonoBehaviour class using EntityManager but I keep getting this error:

InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckReadAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x4ac1a530 + 0x00052> in <2f14d49edc704940aee557642343f344>:0
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckReadAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at C:/buildslave/unity/build/Runtime/Export/AtomicSafetyHandle.bindings.cs:143)
Unity.Entities.ArchetypeChunk.GetNativeArray (Unity.Entities.ArchetypeChunkEntityType archetypeChunkEntityType) (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Entities/Iterators/ArchetypeChunkArray.cs:63)
Unity.Transforms.TransformSystem.UpdateFrozen () (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Transforms/TransformSystem.cs:320)
Unity.Transforms.TransformSystem.OnUpdate (Unity.Jobs.JobHandle inputDeps) (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Transforms/TransformSystem.cs:1178)
Unity.Entities.JobComponentSystem.InternalUpdate () (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Entities/ComponentSystem.cs:508)
Unity.Entities.ScriptBehaviourManager.Update () (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Entities/ScriptBehaviourManager.cs:77)
Unity.Entities.ScriptBehaviourUpdateOrder+DummyDelagateWrapper.TriggerUpdate () (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Entities/ScriptBehaviourUpdateOrder.cs:703)

I figured that since I’ve disrupted the arrays by destroying an entity using EntityManager, the ECS context doesn’t like this. I tried using a system’s PostUpdateCommand. I got an instance of the system using World.GetOrCreateManager(). On the call to EntityCommandBuffer.DestroyEntity(), I got the following error:

InvalidOperationException: The NativeArray has been deallocated, it is not allowed to access it
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrowNoEarlyOut (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) <0x505961b0 + 0x00052> in <2f14d49edc704940aee557642343f344>:0
Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle.CheckWriteAndThrow (Unity.Collections.LowLevel.Unsafe.AtomicSafetyHandle handle) (at C:/buildslave/unity/build/Runtime/Export/AtomicSafetyHandle.bindings.cs:153)
Unity.Entities.EntityCommandBuffer.EnforceSingleThreadOwnership () (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Entities/EntityCommandBuffer.cs:556)
Unity.Entities.EntityCommandBuffer.DestroyEntity (Unity.Entities.Entity e) (at C:/Users/Marnel/AppData/Local/Unity/cache/packages/staging-packages.unity.com/com.unity.entities@0.0.12-preview.21/Unity.Entities/EntityCommandBuffer.cs:684)

I’m stuck. What are my other options?

Any chance for simplified code snippet, with error reproduction?

MonoBehaviour isn’t a good place to do that
create a ComponentSystem, query entities and destroy using PostUpdateCommands

I’m integrating a framework made in ECS to an existing nonECS project. What you’re saying is not always possible or disrupts too much code. I just want to manipulate entities/components from outside ECS safely. I don’t think it’s impossible with the current system.

ECS entities can not be manipulated outside ECS. At least not in safe manner.
You need use Hybrid ECS approach for that purpose.

After more investigation, I’ve found out that everything works if I just remove the Static component of the entities I’m trying to modify. Is this a potential bug? I do need the Static component as it allows further optimization among my systems.

Regarding the first question: you may just do what you did, it is safe. EntityManager will Complete all jobs currently accessing ECS. Of course this is not the most performant way to do it. Using a command buffer, as you already tried to do, is better. To get one you can actually use in the main thread get a barrier system, eg EndFrameBarrier and use CreateCommandBuffer on it.

I think the static issue is not related.

1 Like

Yes they can, any call to EntityManager forces a sync so it’s safe.

This is a known issue with static and the TransformSystem.
Discussion here and a solution (if you’re willing to modify the TransformSystem)
https://discussions.unity.com/t/721706/3

3 Likes

They can and they do :slight_smile: Hybrid it’s absolutely same as pure just with couple of wrappers for manipulating heap objects, most part of things (under hood) do pure stuff there and here :slight_smile:
And agree with @tertle , it’s just call Static changes untill Pending Frozen not processed.

1 Like

Yep just realizing, while reading thread. I guess more to learn for me :wink:

The TransformSystem hack works. Thanks!