나도 깜짝 놀랐는데 'ECS & C# Job System 샘플 프로젝트 따라잡기 #2'라는 이름의 포스트를 작성하고 벌써 1년이 넘게 지났다. 슬슬 3편을 써볼까 하고 git pull을 받았는데 너무 많이 바뀌었다. 그래서 그냥 처음부터 다시 시작한다. 기존 1,2편도 기록을 위해 남겨둔다.
2019/03/13 - [개발/Unity] - [Unity][DOTS] ECS & C# Job System, 샘플 프로젝트 따라잡기 #1
2019/03/29 - [개발/Unity] - [Unity][DOTS] ECS & C# Job System, 샘플 프로젝트 따라잡기 #2
DOTS 공식 샘플 프로젝트는 Github에 올라가 있는데 주소는 아래와 같다. 다행히 주소까지 바뀌지는 않았다.
https://github.com/Unity-Technologies/EntityComponentSystemSamples
공식 샘플 프로젝트 관련 최신 소식은 유니티 포럼 사이트의 아래 공지 글에서 확인할 수 있다.
https://forum.unity.com/threads/samples.522629/
Github 첫 페이지에 뜨는 README.md 파일을 보면 프로젝트 인스톨 가이드가 적혀있다. 한국어로 그대로 옮겨보겠다.
- 유니티 에디터에서 프로젝트를 새로 만든다 (최신 버전의 DOTS 패키지를 설치하기 위해 2019.3.0f1 또는 그 이상 버전의 유니티를 설치해야 한다).
- 에디터에서 패키지 매니저를 실행한다 (메뉴: Window > Package Manager)
- 윈도우 상단의 Advanced 메뉴를 열고 "Show preview packages' 옵션을 켠다.
- Hybrid Renderer 패키지를 찾아서 프로젝트에 추가한다.
그러면 의존(dependency) 관계에 있는 Entities 패키지가 추가된다. 다시 Entities 패키지가 의존성을 갖는 Burst, Collections, Jobs, Mathematics 같은 패키지들이 재귀적으로 쭉 추가된다. 여기까지 하면 새로 만든 프로젝트에서 바로 DOTS를 사용할 수 있다.
샘플 프로젝트는 크게 Advanced 그룹과 HelloCube 그룹으로 나뉜다. 일단 HelloCube 그룹을 쭉 살펴보고 나중에(그 언젠가..) Advanced도 분석해 보겠다.
HelloCube 그룹의 예제 "1. ForEach"부터 시작한다. 폴더 구조는 아주 간단하다. ForEach 씬 파일과 README 문서, 두 개의 스크립트가 들어있다.
README.md 파일을 열어보면 이 예제에 대한 대략적인 설명이 적혀있다. 참고로 이 문서에 ECS라는 말이 계속 나오는데 DOTS의 예전 이름이 ECS다. 정확히는 ECS가 DOTS의 주요 구성 요소 중 하나인데 자세한 이야기는 나중에 하기로 하고 일단 넘어가자. 발번역이지만 핵심만 한국어로 옮겨보겠다.
이 예제는 두 개의 큐브가 회전하는 간단한 ECS 시스템을 구현한 것이다. 또한 이 예제는 ECS가 데이터와 기능적인 부분으로 나뉘어 있다는 것을 보여준다. 데이터는 Component(ECS의 'C')에 저장된다. 반면에 기능적인 부분은 System(ECS의 'S')을 이용해서 작성한다. 'RotationSpeedSystem_ForEach'가 System인데 'RotationSpeed_ForEach' Component에 저장된 데이터를 이용해서 오브젝트를 회전시킨다.
ForEach 씬(scene)을 열면 씬 뷰에 커다란 정육면체(cube) 위에 작은 정육면체가 붙어 있는 메쉬 덩어리가 보인다. 씬 뷰에서 재생 버튼을 누르면 오브젝트가 Y축 방향으로 회전하는 것을 볼 수 있다.
이제 코드를 살펴보자. 먼저 'RotationSpeed_ForEach'는 IComponentData 인터페이스를 구현한 구조체다. 초당 몇 도를 회전할지에 대한 정보만 갖는다. 즉, 기능적인 부분은 없고 데이터만 갖는 구조체다.
[GenerateAuthoringComponent]
public struct RotationSpeed_ForEach : IComponentData
{
public float RadiansPerSecond;
}
다음으로 'RotationSpeedSystem_ForEach'는 SystemBase를 상속 받은 System 클래스다.
public class RotationSpeedSystem_ForEach : SystemBase
{
// OnUpdate runs on the main thread.
protected override void OnUpdate()
{
float deltaTime = Time.DeltaTime;
// Schedule job to rotate around up vector
Entities
.WithName("RotationSpeedSystem_ForEach")
.ForEach((ref Rotation rotation, in RotationSpeed_ForEach rotationSpeed) =>
{
rotation.Value = math.mul(
math.normalize(rotation.Value),
quaternion.AxisAngle(math.up(), rotationSpeed.RadiansPerSecond * deltaTime));
})
.ScheduleParallel();
}
}
Entities.ForEach 람다(lambda)식을 이용해서 Entity(ECS의 'E', 일단 GameObject와 비슷한 개념이라고 생각하자)들을 무한히 회전시킨다. 이 예제에는 Entity가 한 개 밖에 없지만 Entity가 추가되면 RotationSpeed_ForEach Compnent가 붙은 모든 Entity들이 이 System에 의해 회전하게 된다. 즉, 이 클래스는 데이터는 없고 기능적인 부분만 수행한다.
RotationSpeed_ForEach 구조체 코드를 다시 보면 [GenerateAuthoringComponent] 속성(attribute)이 붙어있다. 이게 붙으면 유니티 에디터의 Inspector 창에 해당 구조체의 public 필드(filed)가 보이고 값을 수정할 수도 있다.
이상으로 첫번째 예제를 요리조리 뜯어봤다. 2편에서는 두 번째 예제 '2. IJobChunk'를 분석해보겠다. 끝.
'개발 > Unity' 카테고리의 다른 글
[Unity] 콘솔 창 Error Pause 옵션 (408) | 2020.03.23 |
---|---|
[Unity][DOTS] Unity.Mathematics 라이브러리 사용하기 (6) | 2020.01.28 |
[Unity][DOTS] System에서 Entity 데이터에 접근하는 다양한 방법 (2) | 2019.10.24 |
[Unity][DOTS] ECS System에서 기존(Non-ECS) Component 제어하기 (0) | 2019.09.17 |
[Unity] NGUI + Spine 연동 (2) | 2019.08.30 |
댓글