Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

ECS and Prefabs organisation

Discussion in 'Entity Component System' started by sdvoynikov, Dec 2, 2019.

  1. sdvoynikov

    sdvoynikov

    Joined:
    Nov 24, 2012
    Posts:
    7
    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

    Code (CSharp):
    1.  
    2. public struct SpawnObstacle : IComponentData {
    3.     public Entity Prefab;
    4. }
    5.  
    6. public class SpawnObstacleAuthoring : MonoBehaviour, IConvertGameObjectToEntity, IDeclareReferencedPrefabs {
    7.     [SerializeField] private ObstacleAuthoring _prefab = default;
    8.  
    9.     public void Convert(Entity entity,
    10.                                     EntityManager dstManager,
    11.                                     GameObjectConversionSystem conversionSystem) {
    12.         dstManager.AddComponentData(entity, new SpawnObstacle {
    13.                 Prefab = conversionSystem.GetPrimaryEntity(_prefab.gameObject),
    14.         });
    15.     }
    16.  
    17.     public void DeclareReferencedPrefabs(List<GameObject> referencedPrefabs) {
    18.         referencedPrefabs.Add(_prefab.gameObject);
    19.     }
    20. }
    21.  
    22. public class SpawnObstacleSystem : JobComponentSystem {
    23.     private EntityQuery _spawnObstacle;
    24.     private EntityQuery _obstacles;
    25.     private EntityCommandBufferSystem _commandBufferSystem;
    26.  
    27.     protected override void OnCreate() {
    28.         base.OnCreate();
    29.         _spawnObstacle = GetEntityQuery(typeof(SpawnObstacle));
    30.         _obstacles = GetEntityQuery(typeof(Obstacle));
    31.         _commandBufferSystem = World.
    32.             GetOrCreateSystem<BeginInitializationEntityCommandBufferSystem>();
    33.     }
    34.  
    35.     [BurstCompile]
    36.     private struct SpawnJob : IJobParallelFor {
    37.         public EntityCommandBuffer.Concurrent CommandBuffer;
    38.         [ReadOnly] public Entity Prefab;
    39.  
    40.         public void Execute(int index) {
    41.             var obstacleEntity = CommandBuffer.Instantiate(index, Prefab);
    42.         }
    43.     }
    44.  
    45.     protected override JobHandle OnUpdate(JobHandle inputDeps) {
    46.         var ObstaclesNumber = 50;
    47.         var obstaclesDelta = ObstaclesNumber - _obstacles.CalculateEntityCount();
    48.  
    49.         if (obstaclesDelta > 0) {
    50.             var commandBuffer = _commandBufferSystem
    51.                     .CreateCommandBuffer().ToConcurrent();
    52.             inputDeps = new SpawnJob {
    53.                     CommandBuffer = commandBuffer,
    54.                     Prefab = _spawnObstacle.GetSingleton<SpawnObstacle>().Prefab,
    55.             }.Schedule(obstaclesDelta, 8, inputDeps);
    56.             _commandBufferSystem.AddJobHandleForProducer(inputDeps);
    57.         }
    58.  
    59.         return inputDeps;
    60.     }
    61. }
    62.  
    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?
     
    Last edited: Dec 2, 2019
  2. GilCat

    GilCat

    Joined:
    Sep 21, 2013
    Posts:
    676
    You can make SpawnObstacle an IBufferElementData and i think that is the way to go there. You can have the ObstacleType too so you can pick the right one to instantiate.
     
  3. sdvoynikov

    sdvoynikov

    Joined:
    Nov 24, 2012
    Posts:
    7
    @GilCat Thanks for your suggestion, it sounds like what I need, I'll give it a try.