I’m trying to use Unity DOTS for a game project, however I keep hitting the following error mentionned above when trying to instantiate Entities referenced in a BlobArray
:
ArgumentException: System.ArgumentException: System.String Unity.Entities.EntityComponentStore::AppendRemovedComponentRecordError(Unity.Entities.Entity,Unity.Entities.ComponentType)
This Exception was thrown from a function compiled with Burst, which has limited exception support.
My logic up until now is to create a BlobArray
of InstantiatableEntityData
, which contains two things: The hash of a string that would function like an ID, and an Entity. Each time my BuildingScreenSystem
receives an input, it reads an ID and compares it to its BlobArray
to see which Entity is currently requested; It then instantiates this Entity. It’s during this last part that it throws the error mentionned in the title.
Here’s are the two relevant files:
GameAuthoring.cs
, which creates the singleton component Game
, containing the BlobAssetReference
.
public class GameAuthoring : MonoBehaviour
{
[SerializeField] private List<InstantiatableEntity> instantiatableEntities;
private class Baker : Baker<GameAuthoring>
{
public override void Bake(GameAuthoring authoring)
{
var entity = GetEntity(TransformUsageFlags.None);
AddComponent(entity, new Game()
{
State = GameState.Starting,
EntityPool = CreateEntityPool(authoring.instantiatableEntities)
});
}
private BlobAssetReference<InstantiatableEntityPool> CreateEntityPool(List<InstantiatableEntity> instantiatableEntities)
{
var builder = new BlobBuilder(Allocator.Temp);
ref InstantiatableEntityPool instantiatableEntityPool = ref builder.ConstructRoot<InstantiatableEntityPool>();
// Allocate enough room the entities in the pool. Use the returned BlobBuilderArray
// to fill in the data.
var entitiesCount = instantiatableEntities.Count;
BlobBuilderArray<InstantiatableEntityData> arrayBuilder = builder.Allocate(
ref instantiatableEntityPool.Entities,
entitiesCount
);
for (int i = 0; i < entitiesCount; ++i)
{
var entry = instantiatableEntities[i];
arrayBuilder[i] = new InstantiatableEntityData()
{
EntityID = entry.entityID.GetHashCode(),
Entity = GetEntity(entry.entity, TransformUsageFlags.Dynamic)
};
}
var result = builder.CreateBlobAssetReference<InstantiatableEntityPool>(Allocator.Persistent);
builder.Dispose();
return result;
}
}
}
public struct Game : IComponentData
{
public GameState State;
public BlobAssetReference<InstantiatableEntityPool> EntityPool;
}
[Serializable]
public struct InstantiatableEntity
{
public string entityID;
public GameObject entity;
}
public struct InstantiatableEntityData
{
public int EntityID;
public Entity Entity;
}
public struct InstantiatableEntityPool
{
public BlobArray<InstantiatableEntityData> Entities;
}
And BuildingScreenSystem.cs
, the first system using this array to instantiate a given unit at a fixed point.
partial struct BuildingScreenSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<Game>();
}
// Accessing BuildingScreen, can't use BurstCompile
public void OnUpdate(ref SystemState state)
{
if (!Input.GetMouseButtonDown(0))
return;
var ecb = new EntityCommandBuffer(Allocator.Temp);
var selectedID = BuildingScreenSingleton.Instance.SelectedPrefabID;
ref var entityPool = ref SystemAPI.GetSingleton<Game>().EntityPool.Value;
for (int i = 0; i < entityPool.Entities.Length; ++i)
{
Debug.Log($"{entityPool.Entities[i].Entity}");
if (entityPool.Entities[i].EntityID == selectedID)
{
Debug.Log("Found match! Spawning now...");
var newEntity = ecb.Instantiate(entityPool.Entities[i].Entity);
ecb.SetComponent(newEntity, new LocalTransform()
{
Position = new float3(0, 10, 0),
Rotation = quaternion.identity,
Scale = 1f
});
}
}
ecb.Playback(state.EntityManager);
ecb.Dispose();
}
}
I know the code successfully matches the two IDs thanks to my second log, but I can’t find the referenced entity given to me by the first log in the Entities Hierarchy
.
So I think my error probably comes from misunderstanding how BlobAssets work, but I still can’t find any reference or explanation to this error online, so I feel like I’ve hit a wall…
Does anyone more knowledgable than me in DOTS see the issue in this code, or recognize the error?