Search Unity

DOTS/ECS spawn random prefab from array

Discussion in 'General Discussion' started by Ltn-Mc-Bacon, Nov 14, 2020.

  1. Ltn-Mc-Bacon

    Ltn-Mc-Bacon

    Joined:
    May 17, 2017
    Posts:
    1
    Hello!
    I'm trying to spawn random prefabs onto my map every X seconds using ECS, but components are only able to hold basic types and not arrays.

    How do I access an array of prefabs in my spawner system and instantiate them?
    If I could attach the script to an empty gameobject and drag-n-drop my prefabs onto a public array that would be ideal!

    Anyone knows how to do?
     
  2. EternalAmbiguity

    EternalAmbiguity

    Joined:
    Dec 27, 2014
    Posts:
    3,144
    This belongs in the DOTS forum.

    How I'm doing it:

    The following is my control script.
    Code (CSharp):
    1.  
    2.     void Start()
    3.     {
    4.         em = World.DefaultGameObjectInjectionWorld.EntityManager;
    5.         var settings = GameObjectConversionSettings.FromWorld(World.DefaultGameObjectInjectionWorld, blobAssetStore);
    6.         settings.ConversionFlags = GameObjectConversionUtility.ConversionFlags.AssignName;
    7.         weaponEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(weaponMainLowPrefab, settings);
    8.         enemyEntity = GameObjectConversionUtility.ConvertGameObjectHierarchy(enemyPrefab, settings);
    9.     }
    10.  
    11.     Entity CreateEnemy(int state, int X, int Y)
    12.     {
    13.         var instance2 = em.Instantiate(enemyEntity);
    14.         var actionThreshold = 1f;
    15.         var health = 100f;
    16.         switch (state)
    17.         {
    18.             case 0:
    19.                 actionThreshold = 0.1f;
    20.                 health = 100f;
    21.                 break;
    22.         }
    23.         switch(mapStart)
    24.         {
    25.             case Starts.RegularGrowth:
    26.                 health = 10f;
    27.                 break;
    28.         }
    29.         var position = positionMapping[X, Y];
    30.  
    31.         var we = new EnemyEntity()
    32.         {
    33.             actionThreshold = actionThreshold,
    34.             actionValue = 0,
    35.             health = health,
    36.             lerp = 0f,
    37.             mapCorner0 = mapCorners[0],
    38.             mapCorner1 = mapCorners[2],
    39.             newPosition = position,
    40.             oldPosition = position,
    41.             state = state,
    42.             weaponEntity = weaponEntity,
    43.             X = X,
    44.             Y = Y
    45.         };
    46.         em.SetComponentData(instance2, new Translation { Value = position });
    47.         em.SetComponentData(instance2, new Rotation { Value = quaternion.identity });
    48.         em.SetComponentData(instance2, we);
    49.         return instance2;
    50.     }
    51.  
    The prefabs must already have the components, with the [GenerateAuthoringComponent] tag above the struct, and a ConvertToEntity component (with ConvertAndDestroy selected).

    The following is the enemy system.
    Code (CSharp):
    1.  
    2. var weaponCreation = new NativeQueue<WeaponCreationStruct>(Allocator.TempJob);
    3.         var parallel = weaponCreation.AsParallelWriter();
    4. Entities
    5.                 .WithName("EnemySystem")
    6.             .WithBurst(Unity.Burst.FloatMode.Default, Unity.Burst.FloatPrecision.Standard, true)
    7.             .ForEach((Entity entity, int nativeThreadIndex, ref Translation translation, ref Rotation rotation, ref EnemyEntity enemy, in LocalToWorld localToWorld) =>
    8.             {
    9.                         parallel.Enqueue(new WeaponCreationStruct()
    10.                         {
    11.                             velocity = localToWorld.Forward * 55 /** velocity*/,
    12.                             entity = enemy.weaponEntity,
    13.                             weaponEntity = new WeaponEntity(WeaponType.MainLow, enemy.mapCorner0.x, enemy.mapCorner1.x, enemy.mapCorner0.y, enemy.mapCorner1.y),
    14.                             position = front, // any lower and it collides with the player when the player moves
    15.                             rotation = frontDir,
    16.                         });
    17.             }).ScheduleParallel()
    18.         Dependency.Complete();
    19.         if (weaponCreation.Count > 0)
    20.         {
    21.             int count = weaponCreation.Count;
    22.             for (int i = 0; i < count; i++)
    23.             {
    24.                 var current = weaponCreation.Dequeue();
    25.                 var instance = EntityManager.Instantiate(current.entity);
    26.                 EntityManager.SetComponentData(instance, new Translation { Value = current.position });
    27.                 EntityManager.SetComponentData(instance, new Rotation { Value = current.rotation });
    28.                 EntityManager.SetComponentData(instance, new Unity.Physics.PhysicsVelocity() { Linear = current.velocity });
    29.                 EntityManager.SetComponentData(instance, current.weaponEntity);
    30.             }
    31.         }