-
Unity ECS(Entity Component System)2023년 10월 30일
- 유니얼
-
작성자
-
2023.10.30.:10
728x90Unity ECS의 개념 소개
Unity ECS는 엔티티 컴포넌트 시스템으로, 게임 오브젝트를 구성하는 데이터를 엔티티, 컴포넌트 및 시스템으로 분리합니다. 이를 통해 개발자는 코드의 가독성과 유지 보수성을 향상시킬 수 있습니다. 또한, ECS는 병렬 처리를 통해 높은 성능을 제공합니다.
https://blog.unity.com/kr/technology/on-dots-entity-component-system
DOTS 기술 소개: 엔티티 컴포넌트 시스템 | Unity Blog
유니티에서 구축하려고 하는 그 다음 레이어는 매우 큰 프로젝트로서, “게임 엔진” 레이어이며 “렌더러”, “물리 시스템”, “네트워킹”, “입력”, “애니메이션” 등으로 구성되며 현재
blog.unity.com
Unity ECS를 사용하는 이유
Unity ECS를 사용하면 개발자는 코드를 더 깔끔하게 유지할 수 있습니다. 또한, 성능을 향상시키고 유연성을 높여 새로운 기능을 쉽게 추가할 수 있습니다. Unity ECS는 복잡한 시스템을 쉽게 구축할 수 있는 강력한 도구입니다.
Unity ECS 핵심 요소
1. Archetype
Archetype은 데이터 지향적인 방식으로 코드를 작성하고 데이터를 저장하는 방법 중 하나입니다. 데이터 지향적인 방식은 데이터를 Packing하고 Loop를 돌려서 반복 처리하는 방식입니다. Archetype은 비슷한 구성 요소를 가진 데이터를 그룹화하고 저장합니다. 각 Archetype에는 동일한 구성 요소의 데이터가 저장됩니다.
예를 들어, "몬스터" Archetype은 몬스터의 위치(Position), 방향(Rotation), 체력(Health) 등과 같은 구성 요소를 가진 데이터를 모두 그룹화합니다. 이렇게 데이터를 Packing할 경우 필요한 구조에 대한 정보를 이미 알고 있기 때문에 원하는 타입의 그룹을 가져와서 연산만 하면 됩니다. 이러한 데이터 구조는 유니티 뿐만 아니라 언리얼 엔진에서도 사용됩니다.
2, Memory Chunk
Archetype을 살펴보면 데이터를 패킹(Packing)할 때 배열로 묶는 것을 볼 수 있습니다. 각 배열에는 한 가지 유형의 컴포넌트 데이터가 저장됩니다. 그럼 데이터를 어떤 단위로 배열로 만들어서 저장하고 관리할까요? 여기서 Chunk(청크)라는 개념이 중요합니다. Chunk는 일정한 크기(일반적으로 16KB)의 메모리 블록을 나타냅니다. 각 Chunk는 비슷한 구성 요소를 가진 데이터를 묶어서 저장합니다. 데이터를 Chunk로 구성하면 메모리 효율적인 배치와 데이터 처리를 할 수 있게 됩니다.
아래 예시를 통해 이 개념을 이해해 보겠습니다.
위그림에서 GameObject 데이터를 저장할 때 Chunk로 관리하고 있습니다. ArchetypeA의 GameObject 데이터는 Chunk[2]에 저장되어 관리되고, 나머지 ArchetypeB 및 ArchetypeC는 Chunk[1]에 GameObject 데이터를 저장하고 관리하고 있다고 생각하면 됩니다. Unity에서는 이러한 Archetype 방식을 적용하기 위해 ECS(Entity Component System)를 사용하여 데이터를 수집하고 처리합니다. ECS는 데이터 수집 및 처리를 위해 설계된 시스템입니다.
Unity ECS 구성 요소
Component
컴포넌트는 엔티티의 속성을 정의하는 데이터입니다. 예를 들어, 위치, 회전, 크기 등의 정보를 컴포넌트로 표현할 수 있습니다.Entity
엔티티는 게임 오브젝트의 핵심 구성 요소입다. Component들의 집합으로, 하나의 오브젝트(그룹)를 이룹니다. 예를 들어, 몬스터는 위치(Position), 방향(Rotation), 크기(Scale) 데이터로 구성된 Entity입니다.System
시스템은 컴포넌트를 업데이트하는 로직입니다. 시스템은 특정 조건을 충족하는 엔티티를 선택하여 컴포넌트를 조작합니다. 예를 들어, 몬스터 이동 또는 회전과 같은 처리를 담당합니다.Unity ECS의 장점
1) 성능 향상
Unity ECS는 데이터 지향적 접근 방식을 통해 더 효율적인 코드 실행을 가능하게 합니다. 이는 게임의 성능 향상에 큰 기여를 합니다.
2) 유연성과 확장성
ECS 아키텍처는 시스템, 엔티티, 컴포넌트를 분리함으로써 유연성과 확장성을 제공합니다. 이는 대규모 프로젝트에서 특히 유용합니다.
Unity ECS의 사용법 및 예제
Step 1 시스템 생성과 구성
Unity ECS에서 시스템을 만들고 구성하는 방법을 알아보겠습니다. 시스템은 엔티티를 선택하고 컴포넌트를 조작하는 역할을 합니다.
Step 2 엔티티와 구성 요소 추가
Unity ECS에서 엔티티를 생성하고 컴포넌트를 추가하는 방법을 소개합니다. 이를 통해 게임 오브젝트를 동적으로 생성 및 제어할 수 있습니다.
Step 3 시스템 업데이트 로직 작성
Unity ECS에서 시스템을 업데이트하는 로직을 작성하는 방법을 알아봅니다. 시스템은 프레임마다 업데이트되어 게임 로직을 실행합니다.
큐브를 회전시키는 기능을 ECS로 구현한다고 예시를 들어봅시다. 큐브는 RotationSpeed 컴포넌트를 통해 회전 속도를 설정하고, RotationSystem을 통해 실제 회전을 수행합니다.
1. 회전 속도 컴포넌트 생성
먼저, 회전 속도를 나타내는 컴포넌트를 생성합니다. RotationSpeed 컴포넌트는 IComponentData를 구현하여 초당 라디안 단위의 회전 속도를 저장합니다.
using Unity.Entities; // Unity.Entities 네임스페이스 필요 // 회전 속도를 저장하는 컴포넌트 데이터 구조 public struct RotationSpeed : IComponentData { public float RadiansPerSecond; // 초당 라디안 단위 회전 속도 }
2. 회전 속도 Authoring 컴포넌트 생성
다음으로, 회전 속도를 실제 큐브에 적용하기 위해 Authoring 컴포넌트를 생성합니다. 이 컴포넌트는 MonoBehavior를 상속하며, 에디터에서 회전 속도를 설정할 수 있습니다.
using Unity.Entities; using UnityEngine; // Authoring 컴포넌트는 일반적인 MonoBehavior입니다. public class RotationSpeedAuthoring : MonoBehaviour { public float DegreesPerSecond = 360.0f; // 베이커 클래스: 컴포넌트 데이터를 엔티티에 추가하는 역할을 합니다. class Baker : Baker<RotationSpeedAuthoring> { public override void Bake(RotationSpeedAuthoring authoring) { // 엔티티에 회전 속도 컴포넌트를 추가합니다. var entity = GetEntity(TransformUsageFlags.Dynamic); AddComponent(entity, new RotationSpeed { RadiansPerSecond = math.radians(authoring.DegreesPerSecond) }); } } }
3. 회전을 처리하는 시스템 구현
마지막으로, 회전을 처리하는 시스템을 구현합니다. 시스템은 주기적으로 실행되며, 회전 속도에 따라 큐브를 회전시킵니다.
using Unity.Entities; using Unity.Mathematics; using Unity.Transforms; public partial class RotationSystem : SystemBase { // OnUpdate 메서드: 시스템 업데이트 루프 protected override void OnUpdate() { float deltaTime = Time.DeltaTime; // LocalTransform 컴포넌트와 RotationSpeed 컴포넌트를 가진 모든 엔티티에 대해 루프 수행 foreach (var (transform, speed) in SystemAPI.Query<RefRW<LocalTransform>, RefRO<RotationSpeed>>()) { // ValueRW와 ValueRO는 컴포넌트 값에 대한 참조를 반환합니다. // ValueRW는 읽기-쓰기 접근을 위한 안전성 검사를 수행하고, // ValueRO는 읽기 전용 접근을 위한 안전성 검사를 수행합니다. transform.ValueRW = transform.ValueRO.RotateY( speed.ValueRO.RadiansPerSecond * deltaTime); } } }
4, 결과 확인
이제 큐브 게임 오브젝트에 RotationSpeedAuthoring 컴포넌트를 추가하고, 회전 속도를 설정할 수 있습니다. 시스템은 주기적으로 실행되며, 설정한 회전 속도에 따라 큐브가 회전합니다.
마무리
Unity의 Entity Component System (ECS)는 게임 개발에서 높은 성능과 확장성을 위한 효율적인 도구입니다. 데이터 지향적 설계를 통해 ECS는 기존의 오브젝트 지향 프로그래밍 접근법에서 벗어나, 메모리 사용과 병렬 처리를 최적화하여 더 나은 성능을 제공합니다.
또한, ECS는 컴포넌트 기반 아키텍처를 적용하여 코드의 가독성을 향상시키고, 새로운 기능 추가와 확장이 용이하도록 합니다. 이러한 구조는 각 컴포넌트가 독립적으로 작동하고 시스템에 의해 처리되므로 코드의 재사용성이 높아지며 유지 보수가 쉽습니다.
따라서 Unity ECS는 복잡한 게임 로직 관리와 대규모 데이터 처리에 있어 강력한 솔루션으로 작용합니다. 이러한 장점들을 활용하여 개발자들은 고성능 및 대규모 게임을 보다 효율적으로 만들 수 있습니다.
하지만 모든 경우에 ECS가 최선의 선택은 아닙니다. 일부 작업에서는 전통적인 MonoBehaviour 시스템이 더 적합할 수 있으며, 프로젝트 요구 사항에 따라 가장 적합한 방식을 선택하는 것이 중요합니다.
결론적으로, Unity ECS는 그 자체로 강력한 도구입니다. 그러나 그것이 항상 최선의 해결책은 아닙니다. 항상 프로젝트 요구 사항과 목표를 고려하면서 가장 적합한 도구와 접근 방식을 선택하는 것이 중요합니다.
반응형다음글이전글이전 글이 없습니다.댓글