Step 2 - 터렛 회전
관리되지 않는(unmanaged) 시스템(ISystem), 쿼리, 관용적인(idiomatic) foreach의 개념들을 소개합니다.
- "Scripts/Systems" 폴더에 "TurretRotationSystem.cs"이라는 새 파일을 만들고 다음 내용을 넣습니다.
-
using Unity.Burst; using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; // Unmanaged systems based on ISystem can be Burst compiled, but this is not yet the default. // So we have to explicitly opt into Burst compilation with the [BurstCompile] attribute. // It has to be added on BOTH the struct AND the OnCreate/OnDestroy/OnUpdate functions to be // effective. [BurstCompile] partial struct TurretRotationSystem : ISystem { // Every function defined by ISystem has to be implemented even if empty. [BurstCompile] public void OnCreate(ref SystemState state) { } // Every function defined by ISystem has to be implemented even if empty. [BurstCompile] public void OnDestroy(ref SystemState state) { } // See note above regarding the [BurstCompile] attribute. [BurstCompile] public void OnUpdate(ref SystemState state) { // The amount of rotation around Y required to do 360 degrees in 2 seconds. var rotation = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI); // The classic C# foreach is what we often refer to as "Idiomatic foreach" (IFE). // Aspects provide a higher level interface than directly accessing component data. // Using IFE with aspects is a powerful and expressive way of writing main thread code. foreach (var transform in SystemAPI.Query<TransformAspect>()) { transform.RotateWorld(rotation); } } }
- 플레이 모드로 들어가면 모든 것이 재미있게 회전하고 있음을 알 수 있습니다(대포(Cannon)가 다른 것들로부터 점진적으로 분리되어 있으며, 아래 애니메이션은 그것을 잠시 실행시킨 후의 상황을 보여줍니다)
문제는 우리가 만든 foreach가 각각의 transform이 있는 것과 매칭된다는 것입니다. 이것은 탱크 계층의 모든 부분을 회전시킵니다. 포탑의 회전에만 영향을 미치도록 제한해야 합니다. - 플레이 모드에서 나가세요.
- "Scripts/Components" 폴더에 "Turret.cs"이라는 이름의 새 C# 소스 파일을 만들고 다음 내용을 저장합니다.
-
using Unity.Entities; // 빈 구성 요소를 "tag component"라고 합니다. struct Turret : IComponentData { }
- "Scripts/Authoring" 폴더에 "TurretAuthoring.cs"이라는 이름의 새 C# 소스 파일을 만들고 다음 내용을 저장합니다.
-
using Unity.Entities; // MonoBehavior 작성은 일반적인 GameObject 컴퍼넌트입니다. // 그것들은 ECS 데이터를 생성하는 Baking 시스템의 입력을 구성합니다. class TurretAuthoring : UnityEngine.MonoBehaviour { } // Baker는 MonoBehaviours를 작성을 엔티티와 컴퍼넌트로 변환합니다. class TurretBaker : Baker<TurretAuthoring> { public override void Bake(TurretAuthoring authoring) { AddComponent<Turret>(); } }
- TurretAuthoring.cs 파일을 Turret Game Object에 끌어다 놓거나 Game Object 검사기의 Add Component 버튼을 사용하여 "TurretAuthoring" 컴퍼넌트를 "Turret" GameObject에 추가합니다.
- "Turret" GameObject가 선택되어 있는 동안 "Entity Conversion" 패널에서 "Turret" 컴퍼넌트가 엔티티에 있는지 확인합니다(위로 끌어 확장해야 할 수도 있습니다).
- 다음과 같이 "Scripts/Systems" 폴더에 있는 "TurretRotationSystem.cs" 파일의 내용을 수정합니다.
-
using Unity.Burst; using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; [BurstCompile] partial struct TurretRotationSystem : ISystem { [BurstCompile] public void OnCreate(ref SystemState state) { } [BurstCompile] public void OnDestroy(ref SystemState state) { } [BurstCompile] public void OnUpdate(ref SystemState state) { var rotation = quaternion.RotateY(SystemAPI.Time.DeltaTime * math.PI); + // WithAll adds a constraint to the query, specifying that every entity should have such component. + foreach (var transform in SystemAPI.Query<TransformAspect>().WithAll<Turret>()) - foreach (var transform in SystemAPI.Query<TransformAspect>()) { transform.RotateWorld(rotation); } } }
- 플레이 모드로 들어가면 포탑만 회전합니다.
- 플레이 모드에서 나옵니다.
'Unity' 카테고리의 다른 글
ECS(Entity Component System) 튜토리얼: Step 4 - 대포알(Cannon Balls) (0) | 2022.11.23 |
---|---|
ECS(Entity Component System) 튜토리얼: Step 3 - 탱크 이동(Tank movement) (0) | 2022.11.22 |
ECS(Entity Component System) 튜토리얼: Step 1 - Scene 작성(Authoring Scene) (0) | 2022.11.22 |
ECS(Entity Component System) 튜토리얼: 타입들의 접근성(Types accessibility) (0) | 2022.11.22 |
Baking을 통해 데이터 변환(Convert data with Baking) (0) | 2022.11.22 |