원본: https://github.com/Unity-Technologies/EntityComponentSystemSamples/blob/master/DOTS_Guide/ecs_tutorial/README.md

Step 6 - 많은 탱크들을 소환(Spawning many tanks)

한 번만 실행되어야 하는 초기화 시스템을 처리.

  1. "Tank" Game Object를 "EntityScene"에서 "Assets/Prefabs" 폴더로 드래그 앤 드롭합니다.
  2. "EntityScene"에서 "Tank" GameObject(현재는 프리팹 인스턴스)를 삭제합니다.
  3. "Scripts/Components" 폴더에 "Config.cs"이라는 이름의 새 C# 스크립트 파일을 만들고 다음 내용을 저장합니다:
  4. using Unity.Entities;
    
    struct Config : IComponentData
    {
        public Entity TankPrefab;
        public int TankCount;
        public float SafeZoneRadius;
    }
  5. "Scripts/Authoring" 폴더에 "ConfigAuthoring.cs"이라는 이름의 새 C# 소스 파일을 만들고 다음 내용을 저장합니다:
  6. using Unity.Entities;
    
    class ConfigAuthoring : UnityEngine.MonoBehaviour
    {
        public UnityEngine.GameObject TankPrefab;
        public int TankCount;
        public float SafeZoneRadius;
    }
    
    class ConfigBaker : Baker<ConfigAuthoring>
    {
        public override void Bake(ConfigAuthoring authoring)
        {
            AddComponent(new Config
            {
                TankPrefab = GetEntity(authoring.TankPrefab),
                TankCount = authoring.TankCount,
                SafeZoneRadius = authoring.SafeZoneRadius
            });
        }
    }
  7. Hierarchy 창에서 "EntityScene"을 마우스 오른쪽 단추로 클릭하고 Create Empty를 선택한 다음 새 GameObject의 이름을 "Config"로 지정합니다.
  8. "ConfigAuthoring" 컴퍼넌트를 "Config" GameObject에 추가합니다.
  9. "Config" GameObject를 선택하고, 프로젝트 폴더에서 새 필드 "TankPrefab"을 "Tank" 프리팹(드래그 & 드롭)으로 설정하고, "TankCount"를 20으로 설정하고, "SafeZoneRadius"를 15로 설정합니다.
    📝 NOTE
    "SafeZone Radius"는 아직 사용되지 않지만 이후 진행될 튜토리얼과 관련이 있습니다.
  10. "Scripts/Systems" 폴더에 "TankSpawningSystem.cs"이라는 이름의 새 C# 스크립트 파일을 만들고 다음 내용을 저장합니다.
    ⚠ WARNING
    이 시점에서 플레이 모드로 들어가면 탱크가 하나밖에 없다는 사실에 놀랄 수 있습니다. 실제로 20개의 탱크가 있지만, 그들은 모두 같은 위치에서 스폰되고 정확히 같은 방식으로 움직입니다.
  11. using Unity.Burst;
    using Unity.Collections;
    using Unity.Entities;
    using Unity.Mathematics;
    using Unity.Rendering;
    
    [BurstCompile]
    partial struct TankSpawningSystem : ISystem
    {
        [BurstCompile]
        public void OnCreate(ref SystemState state)
        {
        }
    
        [BurstCompile]
        public void OnDestroy(ref SystemState state)
        {
        }
    
        [BurstCompile]
        public void OnUpdate(ref SystemState state)
        {
            var config = SystemAPI.GetSingleton<Config>();
    
            var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();
            var ecb = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged);
    
            var vehicles = CollectionHelper.CreateNativeArray<Entity>(config.TankCount, Allocator.Temp);
            ecb.Instantiate(config.TankPrefab, vehicles);
    
            // 이 시스템은 시작할 때 한 번만 실행해야 합니다. 따라서 한 번 업데이트하면 자동으로 비활성화됩니다.
            state.Enabled = false;
        }
    }
  12. 다음과 같이 "Scripts/Systems" 폴더에 있는 "TankMovementSystem.cs" 파일의 내용을 수정합니다:
  13.  using Unity.Entities;
     using Unity.Mathematics;
     using Unity.Transforms;
     
     partial class TankMovementSystem : SystemBase
     {
         protected override void OnUpdate()
         {
             var dt = SystemAPI.Time.DeltaTime;
     
             Entities
                 .WithAll<Tank>()
    -            .ForEach((TransformAspect transform) =>
    +            .ForEach((Entity entity, TransformAspect transform) =>
                 {
                     var pos = transform.Position;
     
    +                // 이는 탱크의 실제 위치를 수정하는 것이 아니라 3D 노이즈 기능을 샘플링하는 지점만 수정합니다. 
    +                // 이 방식으로, 모든 탱크는 다른 파츠를 사용하고 있으며 고유한 랜덤 플로우 필드를 따라 이동합니다.
    +                pos.y = entity.Index;
                     var angle = (0.5f + noise.cnoise(pos / 10f)) * 4.0f * math.PI;
     
                     var dir = float3.zero;
                     math.sincos(angle, out dir.x, out dir.z);
                     transform.Position += dir * dt * 5.0f;
                     transform.Rotation = quaternion.RotateY(angle);
     
                 }).ScheduleParallel();
         }
     }
  14. 플레이 모드로 들어가면, 20개의 탱크가 각각의 흐름 필드를 따라 이동하기 시작합니다.
  15. 플레이 모드를 종료하세요.
블로그 이미지

RIsN

,