Error when disabeling MaterialMeshInfo directly on Entity creation

Hello everyone,
i am looking for a way to spawn a couple of Entities, but keep them invisible, until a certain point in time later on. It is not a huge amount, so adding the disable-component and removing it is a possibility, but since I have the opportunity to spawn them all at once, with one structual change, instead of 8 for example, I wanted to do that.

The magic seems to be:

ecb.SetComponentEnabled<MaterialMeshInfo>(instance, false);

But I get the following Errors:
image

Unfortunatly, the error messages, nor the call-stack do not tell much about what is happening.
So, here is the complete code:

        public void OnUpdate(ref SystemState state)
        {
            var ecb = new EntityCommandBuffer(Allocator.Temp);
            float distanceFactor = 1.0f;
            foreach (var prefab in SystemAPI.Query<RefRW<StationPrefabComponent>>())
            {
                if (prefab.ValueRW.Spawn)
                {
                    foreach ((var transform, var entity) in SystemAPI.Query<RefRO<LocalTransform>, RefRO<ShipOrientationComponent>>())
                    {
                        Entity instance = ecb.Instantiate(prefab.ValueRW.Value);

                        ecb.SetComponent(instance, new LocalTransform
                        {
                            Position = prefab.ValueRO.Position,
                        });

                        float3 distanceVector = (transform.ValueRO.Position - prefab.ValueRO.Position) * distanceFactor;

                        ecb.AddComponent(instance, new TimerComponent
                        {
                            Timer = math.length(distanceVector),
                        });
                        
                        ecb.AddComponent<GhostOwner>(instance);
                        ecb.SetComponentEnabled<MaterialMeshInfo>(instance, false);
                    }
                    prefab.ValueRW.Spawn = false;
                }
            }

            ecb.Playback(state.EntityManager);
            ecb.Dispose();
        }
    }

I am incredibly sure, that the line ecb.SetComponentEnabled(instance, false); causes the shown errors, since removing them, removes the error.
Is there a simpler way to deactivate rendering on create and later activate rendering back?

Disable burst and see what the full message says

1 Like

Thank you!
I indeed did not add the [BurstDiscard] flag above the System. But this did not change the error-messages.

I replaced the line, where I SetCompenentEnabled with

ComponentLookup<MaterialMeshInfo> mLookUp = state.GetComponentLookup<MaterialMeshInfo>();
mLookUp.SetComponentEnabled(instance, false);

which did not work, because the entity does only exist after the playback. (fair)
error-message:

All entities created using EntityCommandBuffer.CreateEntity must be realized via playback(). One of the entities is still deferred (Index: -1).

My current understanding of this ecb.playback() is, that it is a FiFo-Queue of commands I recorded, so the entity should exist and I can create it, the prefab is valid, since it appears, when I remove the line where I disable the MaterialMeshInfo.

Anyways, while this unfortunately does not answer the reason for the bug, my current solution is to split the spawning of the actual prefab from the spawning of the count-down into two entities/systems.
I am unsure, if this is the right way to go, but this schema at least forces me to differanciate data that the user sees from internal calculation data more clearly.

Current code, if interested:

 [BurstDiscard]
        public void OnUpdate(ref SystemState state)
        {
            var ecb = new EntityCommandBuffer(Allocator.Temp, PlaybackPolicy.MultiPlayback);
            float distanceFactor = 1.0f;
            foreach (var prefab in SystemAPI.Query<RefRW<StationPrefabComponent>>())
            {
                if (prefab.ValueRW.Spawn)
                {
                    foreach ((var transform, var entity) in SystemAPI.Query<RefRO<LocalTransform>, RefRO<ShipOrientationComponent>>())
                    {
                        var instance = ecb.CreateEntity();

                        float3 distanceVector = (transform.ValueRO.Position - prefab.ValueRO.Position) * distanceFactor;
                        Debug.Log("distance: " + math.length(distanceVector).ToString());
                        ecb.AddComponent(instance, new TimerComponent
                        {
                            Timer = 10,
                        });

                        ecb.AddComponent(instance, new StationCreateComponent
                        {
                            Prefab = prefab.ValueRO.Prefab,
                            Position = prefab.ValueRO.Position,
                            RefPosition = transform.ValueRO.Position,
                        });
                    }
                    prefab.ValueRW.Spawn = false;
                }
            }
            
            ecb.Playback(state.EntityManager);
            ecb.Dispose();
        }
    }


    public partial struct StationVisibilitySystem : ISystem
    {
        [BurstDiscard]
        public void OnUpdate(ref SystemState state) 
        {
            var ecb = new EntityCommandBuffer(Allocator.Temp);
            foreach ((var stationCreate, var timer, var entity) in SystemAPI.Query<RefRW<StationCreateComponent>, RefRO<TimerComponent>>().WithEntityAccess())
            {
                if(timer.ValueRO.Timer <= 0)
                {
                    Entity instance = ecb.Instantiate(stationCreate.ValueRO.Prefab);
                    ecb.SetComponent(instance, new LocalTransform
                    {
                        Position = stationCreate.ValueRO.Position,
                    });
                    ecb.DestroyEntity(entity);
                }
            }

            ecb.Playback(state.EntityManager);
            ecb.Dispose();
        }
    }