Unity Entities Tutorial

Unity Entities 1.0.0 Tutorial - Step 6. Spawning many tanks

종잇장 2023. 1. 29. 00:53
한 번만 실행해야 하는 초기화 시스템 처리.

 

1. "EntityScene"에서 "Tank" GameObject를 프로젝트 창의 "Assets/Prefabs" 폴더로 드래그 앤 드롭 합니다.

2. "EntityScene"에서 "Tank" GameObject(현재 Prefab Instance)를 삭제합니다.

3. "Scripts/Authoring" 폴더에 "ConfigAuthoring.cs"라는 새 C# 소스 파일을 만들고 아래 내용을 추가합니다.

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
            });
        }
    }
}    

struct Config : IComponentData
{
    public Entity TankPrefab;
    public int TankCount;
    public float SafeZoneRadius;
}


4. Hierarchy창에서 "EntityScene"을 마우스 오른쪽 버튼으로 클릭하고 Create Empty를 선택한 다음 새 GameObject의 이름을 "Config"로 지정합니다.

5. "Config" GameObject에 "ConfigAuthoring" 컴포넌트를 추가합니다.

6. "Config" GameObject를 선택하고 Project창에 "Tank" Prefab을 "TankPrefab"필드에 드래그 앤 드롭으로 등록해주고, "TankCount"를 20으로 설정하고 "SafeZoneRadius"를 15로 설정합니다.

Note:
"SafeZoneRadius"는 아직 사용되지 않지만 이후 단계와 관련이 있습니다.

 

7. "Scripts/Systems" 폴더에 "TankSpawningSystem.cs"라는 이름의 새 C# 소스 파일을 만들고 아래 코드를 작성합니다.

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;
    }
}

 

Warning:
이 시점에서 플레이 모드에 들어가면 탱크가 하나만 표시되어 놀랄 수 있습니다. 실제로 20개의 탱크가 있지만 모두 같은 위치에 스폰되고 정확히 같은 방식으로 이동합니다.

 

8. "Scripts/Systems" 폴더에 있는 "TankMovementSystem.cs" 파일의 내용을 다음과 같이 수정합니다.

 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.LocalPosition;
 
+                // 이것은 탱크의 실제 위치를 수정하지 않고 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.LocalPosition += dir * dt * 5.0f;
                 transform.LocalRotation = quaternion.RotateY(angle);
 
             }).ScheduleParallel();
     }
 }


9. 플레이 모드로 들어가면 20개의 탱크가 각각 고유한 흐름에 따라 움직이기 시작합니다.

10. 플레이 모드를 종료합니다.

 


원문: https://github.com/Unity-Technologies/EntityComponentSystemSamples/tree/master/EntitiesSamples/EntitiesTutorial#step-6---spawning-many-tanks