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

Step 3 - 탱크 이동

SystemBase 및 병렬 Entities.ForEach를 소개합니다.

  1. "Scripts/Components" 폴더에 "Tank.cs"이라는 이름의 새 C# 소스 파일을 만들고 다음 내용을 저장합니다:
  2. using Unity.Entities;
    
    // Turret에서 했던 것처럼 Tag component를 생성하여 Tank(큐브)를 식별합니다.
    struct Tank : IComponentData
    {
    }
  3. "Scripts/Authoring" 폴더에 "TankAuthoring.cs"이라는 이름의 새 C# 소스 파일을 만들고 다음 내용을 저장합니다.
  4. using Unity.Entities;
    
    class TankAuthoring : UnityEngine.MonoBehaviour
    {
    }
    
    class TankBaker : Baker<TankAuthoring>
    {
        public override void Bake(TankAuthoring authoring)
        {
            AddComponent<Tank>();
        }
    }
  5. "TankAuthoring" 컴퍼넌트를 "Tank" GameObject에 추가합니다.
  6. "Scripts/Systems" 폴더에 "TankMovementSystem.cs"이라는 이름의 새 C# 소스 파일을 만들고 다음 내용을 저장합니다.
  7. using Unity.Entities;
    using Unity.Mathematics;
    using Unity.Transforms;
    
    // ISystem과 달리 SystemBase 시스템은 클래스입니다. 
    // Burst 컴파일되지 않으며 관리되는 코드(Managed Code)를 사용할 수 있습니다.
    partial class TankMovementSystem : SystemBase
    {
        protected override void OnUpdate()
        {
            // Entities.ForEach 아래는 각 항목에 대해 (암시적으로) Burst 컴파일됩니다.
            // 그리고 시간은 관리되는 유형(클래스)인 SystemBase의 멤버입니다.
            // 이것은 그곳에서 직접 시간에 접근하는 것이 불가능하다는 것을 의미한다.
            // 따라서 필요한 값(DeltaTime)을 로컬 변수에 복사해야 합니다.
            var dt = SystemAPI.Time.DeltaTime;
    
            // Entities.ForEach는 쿼리를 처리하는 오래된 접근 방식입니다. 
    		// 이 사용은 권장되지 않지만, 우리가 IFE와 동등한 기능을 얻을 때까지는 편리한 방법입니다.
            Entities
                .WithAll<Tank>()
                .ForEach((TransformAspect transform) =>
                {
                    // 이 값은 ForEach에 매개 변수로 전달되는 람다식입니다.
                    var pos = transform.Position;
    
                    // Unity.Mathematics.noise는 여러 유형의 노이즈 함수들을 제공합니다.
                    // 여기서는 고전적인 펄린 소음(cnoise)을 사용합니다.
                    // Perlin 노이즈에서 흐름장을 생성하는 방법에 관한 상세 내용은 여기에 있습니다:
                    // // https://www.bit-101.com/blog/2021/07/mapping-perlin-noise-to-angles/
                    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);
    
                    // Entities.ForEach 시퀀스의 마지막 함수 호출은 코드가 실행되는 방법을 제어합니다. 
    			// Run (main thread), Schedule (single thread, async) 또는  ScheduleParallel (multiple threads, async).
                // Entities.ForEach는 기본적으로 job 발생기이며, 병렬 jobs를 매우 쉽게 만들 수 있습니다. 
    			// 이는 불행히도 복잡성 비용과 이상한 임의적 제약 조건이 수반되며, 이는 보다 명시적인 접근 방식이 선호되는 이유이다.
    			// 이러한 명시적 접근법(IJobEntity)은 이 튜토리얼의 뒷부분에서 다룹니다.
                }).ScheduleParallel();
        }
    }
     
  8. 플레이 모드로 들어가면 탱크가 흘러가는 영역을 따라 이동하기 시작해야 합니다.
  9. 플레이 모드를 나갑니다.

블로그 이미지

RIsN

,