Editor causing ECS crash

I get a crash that seems to be dependent on the way that the code is run in the Editor.

When I click Play the first time my game runs just fine. When I stop the game and run it a second time it crashes when I try to call CreateEntity on EntityCommanBuffer:

NullReferenceException: Object reference not set to an instance of an object
Unity.Entities.ComponentChunkIterator.UpdateCacheToCurrentChunk (Unity.Entities.ComponentChunkCache& cache, System.Boolean isWriting, System.Int32 indexInComponentGroup) (at Library/PackageCache/com.unity.entities@0.0.12-preview.19/Unity.Entities/Iterators/ComponentChunkIterator.cs:368)
Unity.Entities.ComponentChunkIterator.MoveToEntityIndexAndUpdateCache (System.Int32 index, Unity.Entities.ComponentChunkCache& cache, System.Boolean isWriting) (at Library/PackageCache/com.unity.entities@0.0.12-preview.19/Unity.Entities/Iterators/ComponentChunkIterator.cs:387)
Unity.Entities.EntityArray.get_Item (System.Int32 index) (at Library/PackageCache/com.unity.entities@0.0.12-preview.19/Unity.Entities/Iterators/EntityArray.cs:46)
ECS.Systems.Board.BoardAttachSystem.OnUpdate () (at Assets/Scripts/ECS/Systems/Board/BoardAttachSystem.cs:30)
Unity.Entities.ComponentSystem.InternalUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.19/Unity.Entities/ComponentSystem.cs:374)
Unity.Entities.ScriptBehaviourManager.Update () (at Library/PackageCache/com.unity.entities@0.0.12-preview.19/Unity.Entities/ScriptBehaviourManager.cs:77)
Unity.Entities.ScriptBehaviourUpdateOrder+DummyDelagateWrapper.TriggerUpdate () (at Library/PackageCache/com.unity.entities@0.0.12-preview.19/Unity.Entities/ScriptBehaviourUpdateOrder.cs:703)

This will happen over and over again until i restart Unity. Changing the scenes doesn’t help

I ran into this issue too, although in a totally different use case from an EntityCommandBuffer.

This code breaks after the first run:

public Entity GetFirstEntity(ComponentGroup group)
        {
            var entities = group.GetEntityArray();
            if (entities.Length <= 0)
            {
                throw new InvalidOperationException($"Failed to find an entity in {group}");
            }
            return entities[0];
        }

This alternative code works pretty consistently:

public Entity GetFirstEntity(ComponentGroup group)
        {
            if (group.CalculateLength() <= 0)
            {
                throw new InvalidOperationException($"Failed to find an entity in {group}");
            }

            var entityType = GetArchetypeChunkEntityType();
            var chunks = group.CreateArchetypeChunkArray(Allocator.Temp);
            var entities = chunks[0].GetNativeArray(entityType);
            var entity = entities[0];
            chunks.Dispose();
            return entity;
        }

EntityArray seems to be the culprit. Note that I am using a custom world and manually creating and updating systems.

@DreamingImLatios Uh, yes, I forgot to add this. I was using ComponentGroups. Today I moved all of my systems to using [Inject] and everything works fine.

Just an FYI, there was a UniteLA talk and a forum thread about deprecating injection dependencies.

https://discussions.unity.com/t/713583/25

@psuong That’s why I was using ComponentGroups in the first place. Once we get a properly working alternative I’ll move from [Inject]. Translating between [Inject] method and ComponentGroups is pretty straightforward

CG and Chunk Iteration works perfectly, and I think problem in your logic, but without any context no one can help to solve it :slight_smile:

@eizenhorn See the code example in the second comment ( by @DreamingImLatios ). The exact same thing is happening for me. Whenever I use ComponentGroup.GetEntityArray() I get crashes on EntityCommandBuffer.CreateEntity() in a subsequent launches in GameMode

Again - there is NO some context.
Just for show you, write simple system which creates command buffers and gets entities array from group many times.

public struct SomeComponent : IComponentData
{
    public int Value;
}

[AlwaysUpdateSystem]
public class TestSystem : JobComponentSystem
{
    private ComponentGroup someGroup;
    private TestSystemBarrier barrier;

    protected override void OnCreateManager()
    {
        barrier = World.GetOrCreateManager<TestSystemBarrier>();
        someGroup = GetComponentGroup(typeof(SomeComponent));
    }

    public struct TestParallelJob : IJobParallelFor
    {
        public EntityCommandBuffer.Concurrent ecb;

        public void Execute(int index)
        {
            ecb.CreateEntity(index);
            ecb.AddComponent(index, new SomeComponent()
            {
                Value = index
            });
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            inputDeps.Complete();

            Debug.Log("Check entity array exists");
            EntityArray entities = someGroup.GetEntityArray();
            if (entities.Length == 0)
            {
                Debug.Log("Entities not wxists. Create 10 entities from parallel job!");
                TestParallelJob job = new TestParallelJob()
                {
                    ecb = barrier.CreateCommandBuffer().ToConcurrent()
                };
                job.Schedule(10, 10).Complete();
            }
            else
            {
                Debug.Log($"{entities.Length} entities exists! Try get entities again!");
                EntityArray entities2 = someGroup.GetEntityArray();
                Debug.Log($"And again {entities2.Length} exists!");
            }
      
        }
  
        return inputDeps;
    }
}

All works as expected, after first run, second run and other. With check on space pressed,
3824017--322147--upload_2018-10-26_16-0-39.png

without check space pressed (logging every frame)
3824017--322153--upload_2018-10-26_16-8-58.png

Also all works fine if create system manually

public class TestSystem : MonoBehaviour
{
    private TestJobSystem _jobsystem;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.C))
        {
            _jobsystem = World.Active.GetOrCreateManager<TestJobSystem>();
            ScriptBehaviourUpdateOrder.UpdatePlayerLoop(World.Active);
        }
    }
}

public struct SomeComponent : IComponentData
{
    public int Value;
}

[DisableAutoCreation, AlwaysUpdateSystem]
public class TestJobSystem : JobComponentSystem
{
    private ComponentGroup _someGroup;
    private TestJobSystemBarrier _barrier;

    protected override void OnCreateManager()
    {
        Debug.Log("Created!");
        _barrier = World.GetOrCreateManager<TestJobSystemBarrier>();
        _someGroup = GetComponentGroup(typeof(SomeComponent));
    }

    public struct TestParallelJob : IJobParallelFor
    {
        public EntityCommandBuffer.Concurrent ecb;

        public void Execute(int index)
        {
            ecb.CreateEntity(index);
            ecb.AddComponent(index, new SomeComponent()
            {
                Value = index
            });
        }
    }

    protected override JobHandle OnUpdate(JobHandle inputDeps)
    {
        inputDeps.Complete();

        Debug.Log("Check entity array exists");
        EntityArray entities = _someGroup.GetEntityArray();
        if (entities.Length == 0)
        {
            Debug.Log("Entities not wxists. Create 10 entities from parallel job!");
            TestParallelJob job = new TestParallelJob()
            {
                ecb = _barrier.CreateCommandBuffer().ToConcurrent()
            };
            job.Schedule(10, 10).Complete();
        }
        else
        {
            Debug.Log($"{entities.Length} entities exists! Try get entities again!");
            EntityArray entities2 = _someGroup.GetEntityArray();
            Debug.Log($"And again {entities2.Length} exists!");
        }

        return inputDeps;
    }
}

[UpdateAfter(typeof(TestJobSystem))]
public class TestJobSystemBarrier : BarrierSystem
{
 
}

3824017--322186--upload_2018-10-26_16-44-16.png

The errors come from indexing EntityArray using the index operator [ ].

No. Indexing works fine.

3826546--322522--upload_2018-10-27_7-58-3.png

And all works as expected without errors after many Play\Unplay loops3826546--322525--upload_2018-10-27_7-59-48.png

@eizenhorn Yeah, you’re right. I’ll try to provide a repo with a minimal project reproducing the crash this weekend