Hi! Started to investigate DOTS and stuck with the prefabs organisation problem.
It’s clear when I have a relation one entity archetype = one prefab. I just create something like
public struct SpawnObstacle : IComponentData {
public Entity Prefab;
}
public class SpawnObstacleAuthoring : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs {
[SerializeField] private ObstacleAuthoring _prefab = default;
public void Convert(Entity entity,
EntityManager dstManager,
GameObjectConversionSystem conversionSystem) {
dstManager.AddComponentData(entity, new SpawnObstacle {
Prefab = conversionSystem.GetPrimaryEntity(_prefab.gameObject),
});
}
public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs) {
referencedPrefabs.Add(_prefab.gameObject);
}
}
public class SpawnObstacleSystem : JobComponentSystem {
private EntityQuery _spawnObstacle;
private EntityQuery _obstacles;
private EntityCommandBufferSystem _commandBufferSystem;
protected override void OnCreate() {
base.OnCreate();
_spawnObstacle = GetEntityQuery(typeof(SpawnObstacle));
_obstacles = GetEntityQuery(typeof(Obstacle));
_commandBufferSystem = World.
GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
}
[BurstCompile]
private struct SpawnJob : IJobParallelFor {
public EntityCommandBuffer.Concurrent CommandBuffer;
[ReadOnly] public Entity Prefab;
public void Execute(int index) {
var obstacleEntity = CommandBuffer.Instantiate(index, Prefab);
}
}
protected override JobHandle OnUpdate(JobHandle inputDeps) {
var ObstaclesNumber = 50;
var obstaclesDelta = ObstaclesNumber - _obstacles.CalculateEntityCount();
if (obstaclesDelta > 0) {
var commandBuffer = _commandBufferSystem
.CreateCommandBuffer().ToConcurrent();
inputDeps = new SpawnJob {
CommandBuffer = commandBuffer,
Prefab = _spawnObstacle.GetSingleton<SpawnObstacle>().Prefab,
}.Schedule(obstaclesDelta, 8, inputDeps);
_commandBufferSystem.AddJobHandleForProducer(inputDeps);
}
return inputDeps;
}
}
Now, I have several obstacle types, and want to spawn one of them based on some rule.
First idea was to start with _[SerializeField] private ObstacleAuthoring[ ] prefabs; in Authoring but I can’t hold array of entities in SpawnObstacle component data.
After some thoughts I decided that I can hold some enum type (say ObstacleType) in SpawnObstacle data component and keep one SpawnObstacle entity for every obstacle prefab kind on scene and put them once to NativeArray casting that ObstacleType to index. So I can spawn required kind of prefab this way. Thats sounds doable but I’d like to ask community, is this a correct way or I missed something more obvious?