ECS Assertion Failures while using AddSharedComponentData(EntityQuery)

Using: com.unity.entities: “0.0.12-preview.31” on “Unity 2019.1.0f1”

I’m getting a load of Assertion Failures when trying to run a batch AddSharedComponentData over my EntityQuery using my ComponentSystem.

EDIT: I made an entirely new project from scratch, and simplified everything down immensely, and I’m still getting these errors. This post used to be much more complicated. Here’s the new, and extremely simple ComponentSystem which attaches a RenderMesh by Chunk. Generates Assertion Failures.

Running this system over plain, freshly-created Entities in a brand-new Project:

using System.Collections.Generic;
using Unity.Entities;
using Unity.Rendering;
using UnityEngine;
using ShadowCastingMode = UnityEngine.Rendering.ShadowCastingMode;

namespace BlockEditor {
    [UpdateInGroup(typeof(RenderableSystemGroup))]
    class RenderMeshSystem : ComponentSystem {
        private EntityQuery renderableEntitiesQuery;

        protected override void OnCreate() {
            this.Enabled = true;
            renderableEntitiesQuery = GetEntityQuery(
                ComponentType.Exclude<RenderMesh>() //do not include Entities that are already render-ready.
                );
        }

        protected override void OnUpdate() {
            RenderMesh rmeshie; //<-- what we're building

            //Create the RenderMesh from prepared data.
            rmeshie = new RenderMesh
            {
                mesh = ECSMain.mesh,
                material = ECSMain.material,
                subMesh = 0,
                castShadows = ShadowCastingMode.Off,
                receiveShadows = false
            };

            //Assign the RenderMesh.
            //HERE IS WHERE ERRORS OCCUR:
            ECSMain.mainContext.AddSharedComponentData<RenderMesh>(renderableEntitiesQuery, rmeshie);
        }
    }
}

If you guys would prefer, I can provide this data in a text format for better reading.

Thanks for your time.

So I simplified everything down immensely, removed all extraneous code and put the script into it’s own, blank new Project built on Unity 2019.1.0f1 to try and figure this out.

Still getting these Assertion Failures. Once they occur, the Entity Debugger window breaks and spits out more errors if viewed. I don’t want to dig into the ECS code and try to debug the ECS system code, but my code is so incredibly simple at this point I feel like either it’s an ECS preview bug or I’m just using the API wrong (probably the latter). Are we allowed to use this AddSharedComponentData(EntityQuery) API in a ComponentSystem? I feel like adding a RenderMesh to an Entity in a ComponentSystem should be a pretty common use case…


Did some digging,

Here’s the bit of Unity ECS ChunkDataUtility.cs code that is spitting out the Assertion failures (this is not my code, this is part of Unity):

[Conditional("ENABLE_UNITY_COLLECTIONS_CHECKS")]
public static void AssertAreLayoutCompatible(Archetype* a, Archetype* b)
{
    Assert.IsTrue(AreLayoutCompatible(a,b));
    Assert.AreEqual(a->BytesPerInstance, b->BytesPerInstance);
    Assert.AreEqual(a->ChunkCapacity, b->ChunkCapacity); //<-- ERROR OCCURS HERE

    var typeCount = a->NonZeroSizedTypesCount;

    //If types are identical; SizeOfs, Offsets and BufferCapacities should match
    for (int i = 0; i < typeCount; ++i)
    {
        Assert.AreEqual(a->SizeOfs[i], b->SizeOfs[i]);
        Assert.AreEqual(a->Offsets[i], b->Offsets[i]); //<-- ERROR OCCURS HERE
        Assert.AreEqual(a->BufferCapacities[i], b->BufferCapacities[i]);
    }
}

And yes, it’s correct error. Cos it’s should only change archetype, and not rearrange data, and because RenderMesh has [MaximumChunkCapacity(128)] it’s only can change archetype from current to another with this size (cos if they different it’s can’t just change archetype on chunks it would add\remove\slice chunks). Just add
[MaximumChunkCapacity(128)] limit on other of your types which affected by your query. But remember that other your types with this limit will have cache miss in chunks, when they without RenderMesh.

public class TestSystem : MonoBehaviour
{
    public static RenderMesh Data1 => _instance.data1;
    public RenderMesh data1;
    private static TestSystem _instance;

    private void Awake()
    {
        _instance = this;
    }
}

[MaximumChunkCapacity(128)]
public struct MyCompData : IComponentData
{
    public float            Value;
}

class RenderMeshSystemTest : ComponentSystem {
    private EntityQuery renderableEntitiesQuery1;
    private EntityQuery renderableEntitiesQuery2;
   
    protected override void OnCreate() {
        this.Enabled = true;
        renderableEntitiesQuery1 = GetEntityQuery(
            typeof(MyCompData)
        );
        renderableEntitiesQuery2 = GetEntityQuery(
            typeof(MyCompData),
            typeof(RenderMesh)
        );
        var at1 = EntityManager.CreateArchetype(typeof(MyCompData), typeof(LocalToWorld));
        var e = EntityManager.CreateEntity(at1);
    }
    protected override void OnUpdate()
    {
        if (Input.GetKeyDown(KeyCode.R))
        {
            Debug.Log("Added RM");
            EntityManager.AddSharedComponentData(renderableEntitiesQuery1, TestSystem.Data1);
        }
    }
}


Thanks for your response as usual @eizenhorn !

WOW. I added that to just one of the Components that I was using to index my Entities and it instantly solved the issue! Just got the RenderMesh added to all 500K of my Entities with no problem! Thanks!!

However one final question, I am wondering why it is necessary… Do you know why the RenderMesh has this restriction? I was told the Shared Component Data are referred to using an Index number, which is stored in the Chunk. And that the actual SCD data is stored elsewhere. So shouldn’t adding/removing an SCD per-chunk be as simple as modifying the list of SCD indexes in the chunk header, adding an int and removing an int from the list? Why does the RenderMesh care how many Entities are in it’s Chunk?

Thanks again!

I guess, cos it’s how Rendering works, Unity operate with renderers as batches, and seems chunks should have this limit fill batches properly.
4532731--419971--upload_2019-5-13_9-15-56.png