Component data resetting frame after SetComponent?

I am having trouble setting the GridCell.Occupant and GridCell.GridPosition. I set the gridCell.Occupant and the Debug.Log shows the correct Occupant but when I go to check it in the runtime inspector it shows Entity.Null and GridPosition to be int2[0,0]

GridCell Component:

    public struct GridCell : IComponentData
    {
        public int2 GridPosition;
        public Entity TileVisual;
        public Entity Occupant;
    }
 EntityCommandBuffer ecb = SystemAPI.GetSingletonRW<EndSimulationEntityCommandBufferSystem.Singleton>().ValueRW.CreateCommandBuffer(state.WorldUnmanaged);
            
            foreach (var (furniture, furnitureDataHolder , entity) in SystemAPI.Query<RefRW<Furniture>, RefRO<FurnitureDataHolder>>().WithAll<PlaceFurnitureTag>().WithEntityAccess())
            {
                var cellBuffer = SystemAPI.GetBuffer<OccupiedGridCell>(entity);
                if (cellBuffer.Length == 0)
                {
                    var origin = furniture.ValueRW.Origin;
                    var rotation = furniture.ValueRO.Rotation;
                    ref BlobArray<int2> shapeCells = ref furnitureDataHolder.ValueRO.FurnitureBlobReference.Value.ShapeCells;
                    
                    for (int i = 0; i < shapeCells.Length; i++)
                    {
                        int2 cell = shapeCells[i];
                        int2 rotatedCell = GridUtils.GetRotatedGridPosition(cell, rotation);
                        int2 cellPosition = origin + rotatedCell;
                        
                        foreach (var (gridCell, cellEntity) in SystemAPI.Query<RefRO<GridCell>>().WithEntityAccess())
                        {
                            if(gridCell.ValueRO.GridPosition.Equals(cellPosition))
                            {
                                cellBuffer.Add(new OccupiedGridCell
                                {
                                    GridPosition = cellPosition,
                                    CellEntity = cellEntity
                                });
                                break;
                            }
                        }
                    }
                }

                Debug.Log(cellBuffer.Length);
                foreach (var occupiedCell in cellBuffer)
                {
                    RefRW<GridCell> gridCell = SystemAPI.GetComponentRW<GridCell>(occupiedCell.CellEntity);
                    gridCell.ValueRW.Occupant = entity;
                    Debug.Log("Occupant " + SystemAPI.GetComponent<GridCell>(occupiedCell.CellEntity).Occupant);
                }
                
                BatchMaterialID matId = furnitureDataHolder.ValueRO.FurnitureBlobReference.Value.NormalMaterialID;
                MaterialMeshInfo meshInfo = SystemAPI.GetComponent<MaterialMeshInfo>(furniture.ValueRO.FurnitureVisual);
                meshInfo.MaterialID = matId;
                SystemAPI.SetComponent(furniture.ValueRO.FurnitureVisual, meshInfo);

                foreach (var (request, redrawEntity) in SystemAPI.Query<RefRO<RedrawPathRequest>>().WithDisabled<RedrawPathRequest>().WithEntityAccess())
                {
                    SystemAPI.SetComponentEnabled<RedrawPathRequest>(redrawEntity, true);
                }
                
                ecb.RemoveComponent<PlaceFurnitureTag>(entity);
            }

The Debug.Log on Line 38 getting the component right after shows the correct Entity.
I generate the grid of GridCells and set the grid position here:

foreach (var (generateGrid , entity) in SystemAPI.Query<RefRO<GenerateGrid>>().WithEntityAccess())
            {
                var gridSettings = SystemAPI.GetSingleton<GridSettings>();
                
                int width = gridSettings.Width;
                int height = gridSettings.Height;
                float tileSize = gridSettings.TileSize;
                Entity tilePrefab = gridSettings.TilePrefab;
            
                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        Entity tile = state.EntityManager.Instantiate(tilePrefab);
                        float3 position = GridUtils.GetWorldPosition(new int2(x, y), tileSize, gridSettings.Origin);
                        SystemAPI.SetComponent(tile, LocalTransform.FromPosition(position));
                        RefRW<GridCell> gridCell = SystemAPI.GetComponentRW<GridCell>(tile);
                        gridCell.ValueRW.GridPosition = new int2(x, y);
                    }
                }
            
                state.EntityManager.SetComponentEnabled<GenerateGrid>(entity, false);
            }
        }

Those two places are the only two places I’m setting data in the GridCells . I’m reading data in a couple of other places.

I’ve tried the alternative:

GridCell gridCell = SystemAPI.GetComponent<GridCell>(tile);
gridCell.GridPosition = new int2(x, y);
SystemAPI.SetComponent(tile, gridCell);

When inspecting Grid Cell at Runtime:
image

Any help or advice would be appreciated :slight_smile:

I came here to look for the solution to the same problem. So far what I have found that its inspector causing this. It has nothing to do with our code. If we dont select any entity in the inspector everything works as intended.

Another finding is it only happens if you have “prefab” entities in the component. So if you ll not assign any value to Tile Visual and Occupant variables during baking your code will work fine even if you select entities in inspector.

I believe its clearly a Unity bug, an annoying one for sure.

1 Like

Yeah upon more testing it seems like it works fine if you don’t interact with the inspector.
I’ve also seen someone say that if you don’t have the subscene checked it also will work properly.

I will see if i can load the entities another way but the Tile Visual is just the child of the component and Occupant isn’t set till later (and then instantly unset :smiling_face_with_tear:)