unity-ecs-patterns은(는) 무엇을 하나요?
Unity ECS(Entity Component System)와 DOTS, Jobs, Burst를 마스터하여 고성능 게임을 개발하세요. 데이터 지향 게임을 구축하거나, 성능을 최적화하거나, 대규모 엔티티 수를 다룰 때 사용하세요.
개요
이 기술은 Unity의 ECS(Entity Component System)와 DOTS(Data-Oriented Tech Stack)를 활용한 고성능 게임 개발 패턴을 제공합니다. ECS는 전통적인 객체 지향 방식 대신 데이터 지향 설계를 사용하여 CPU 캐시 효율성을 극대화하고 병렬 처리를 최적화합니다.
주요 특징
- 엔티티(Entity): 단순한 ID로, 데이터는 컴포넌트에 저장됩니다.
- 컴포넌트(Component): 순수 데이터 구조체(struct)로, 로직을 포함하지 않습니다.
- 시스템(System): 특정 컴포넌트 세트를 가진 엔티티들을 처리하는 로직입니다.
지원 환경
- Unity 2020 LTS 이상
com.unity.entities패키지com.unity.jobs패키지 (선택 사항)com.unity.burst패키지 (선택 사항)
시작하기
패키지 설치
# Unity Package Manager를 통해
com.unity.entities
com.unity.jobs
com.unity.burst
기본 ECS 예제
using Unity.Entities;
using Unity.Transforms;
using Unity.Mathematics;
// 컴포넌트 정의
public struct Speed : IComponentData
{
public float Value;
}
// 시스템 정의 (부분 업데이트)
[UpdateInGroup(typeof(SimulationSystemGroup))]
public partial class MoveSystem : SystemBase
{
protected override void OnUpdate()
{
float deltaTime = SystemAPI.Time.DeltaTime;
// 모든 Translation 및 Speed 컴포넌트가 있는 엔티티 쿼리
Entities.ForEach((ref LocalTransform transform, in Speed speed) =>
{
transform.Position += new float3(0, 0, speed.Value * deltaTime);
}).ScheduleParallel();
}
}
핵심 개념
1. 구조적 변경 (Structural Changes)
ECS에서 엔티티의 구조(추가/제거 컴포넌트, 생성/파괴 엔티티)를 변경하는 작업은 비용이 많이 들고 동기화 지점을 생성합니다.
// 엔티티 생성
EntityManager.CreateEntity(typeof(Translation), typeof(Speed));
// 컴포넌트 추가
EntityManager.AddComponent<Health>(entity);
// 엔티티 파괴
EntityManager.DestroyEntity(entity);
팁: 구조적 변경은 가능하면 적게 수행하고, EntityCommandBuffer를 사용하여 Job에서 안전하게 처리하세요.
2. Job 시스템 통합
// IJobEntity를 사용한 병렬 처리
[BurstCompile]
public partial struct MoveJob : IJobEntity
{
public float DeltaTime;
public void Execute(ref LocalTransform transform, in Speed speed)
{
transform.Position += new float3(0, 0, speed.Value * DeltaTime);
}
}
// 시스템 내에서 Job 예약
protected override void OnUpdate()
{
var job = new MoveJob { DeltaTime = SystemAPI.Time.DeltaTime };
job.ScheduleParallel();
}
3. Burst 컴파일러
[BurstCompile] 속성을 Job에 추가하면 Burst 컴파일러가 네이티브 코드로 컴파일하여 성능을 극대화합니다.
4. 쿼리 최적화
// 특정 컴포넌트 조합 쿼리
EntityQuery query = GetEntityQuery(
ComponentType.ReadWrite<LocalTransform>(),
ComponentType.ReadOnly<Speed>()
);
고급 패턴
아키텍처
GameWorld
├── Systems
│ ├── InitializationSystemGroup
│ ├── SimulationSystemGroup
│ └── PresentationSystemGroup
├── Entities
└── Components
데이터 지향 설계 원칙
- 데이터를 로직과 분리: 컴포넌트는 순수 데이터여야 합니다.
- 캐시 지역성 활용: 관련 데이터를 연속적으로 배치하세요.
- 병렬 처리 극대화: 시스템과 Job을 독립적으로 만들고 최대한 병렬화하세요.
문제 해결
- 성능 문제: Profiler를 사용하여 ECS 시스템과 Job의 실행 시간을 측정하세요.
- 구조적 변경 오류: EntityCommandBuffer를 사용하여 Job 내에서 안전하게 변경하세요.
- Burst 호환성: Burst가 지원하지 않는
System.String이나List<T>같은 관리형 타입을 사용하지 마세요.
참고 자료
이 기술은 wshobson/unity-ecs-patterns 저장소를 기반으로 하며, Unity ECS와 DOTS 생태계에서 고성능 게임 개발을 위한 실질적인 패턴과 예제를 제공합니다.