[UNITY],[C#]/TIL : DOTS

[ECS/DOTS] ECS를 이용하여 5000개의 캐릭터를 만들어보자

네,가능합니다 2024. 11. 18. 12:00

모든 자료 출처는 유니티 입니다.

(해당 내용을 리뷰해보며 학습하는 글입니다.)

 

이번 ECS로 최적화 하기는 이전 글에서 만들었던 춤추는 인형 3개를 5000개까지 만들어보고 최적화 하는 작업을 하며 ECS에 익숙해져 보는 시간을 가질것이다.

 

우선 인형의 프리팹을 만들어보자 

 

ECS도 기존 유니티와 동일하게 프리팹을 만들 수 있다.

 

Hierarchy창에서 Sub씬에있는 오브젝트를 프로젝트뷰로 드래그 앤 드롭하면 생성된다.

 

그리고 이 프리팹을 참조하기 위한 Config 컴포넌트를 만들어볼것이다.

 

 

이런 방식으로 프리팹을 지정하고 생성할 개수 혹은 범위도 이 안에서 설정할 수 있도록 할것이다.

 

ConfigAuthoring 스크립트의 내용은 아래와 같다.

 

 

Config 컴포넌트를 보면 프리팹을 엔티티 형태의 값으로 가지고 있다.

 

Authoring 클래스 안에는 기존과 마찬가지로 GameObject의 참조로서 가지고 있는것을 알 수 있다.

 

그리고 Bake메서드 안을 보면 GetEntity를 이용해서 변환을 해서 Config에 넣어주고있다.

 

이 GetEntity메서드는 기존 GameObject 기반의 프리팹을 ECS로 베이크 하는 기능이 있다.

 

다음으로는 이 Config컴포넌트의 설정을 바탕으로 인스턴스를 생성하는 처리를 보도록 하겠다.

 

 

먼저 UpdateInGroup 속성을 사용해서 Update 타이밍을 명시적으로 지정해두었다.

(인스턴스 생성 처리는 다른 Update보다 먼저 실행되도록 한것)

 

그리고 이번에는 OnUpdate만 구현한것이 아닌, OnCreate메서드도 구현되어있는데 이 안에는 RequireForUpdate 메서드를 호출하고 있다. 

이렇게 하면 이 시스템은 월드 내에 Config 컴포넌트가 존재하는 경우에만 실행된다.

 

이렇게 설정해둔 이유는 OnUpdate안에 있다.

 

 

여기서는 SystemAPI의 GetSingleton을 사용해서 월드 안에 오직 하나만 존재하는 Config를 얻고있다.

 

Config가 없을 때는 실행되지 않도록 RequireForUpdate를 지정한것이다.

 

ECS의 subscene은 비동기 로딩이기 때문에 첫번째 프레임부터 Config를 찾을 수 있는것이 아니다.

 

따라서 이런 Config가 없는 경우에 대한 예외처리가 필요했던것이다.

 

다음은 프리팹의 인스턴화이다.

 

Instances 메서드는 대상 프리팹과 생성할 인스턴스 개수를 지정해주어야한다.

대량의 엔티티를 생성할 경우에는 합쳐서 한번만 실행하는것이 절대적으로 빨라, 이런식으로 개수를 지정해주었다.

 

그리고 Config에 설정된 난수 시드를 사용하여 각 인스턴스의 위치나 파라미터를 무작위로 바꾼다.

 

SystemAPI의 GetComponentRW를 사용하면 각 컴포넌트에 대한 접근자를 얻을 수 있는데, 먼저 무작위 위치 및 회전을 생성하여 transform에 대입했고 

 

이어서 Dancer와 Walker의 파라미터를 무작위로 생성하였다.

 

참고로 이 Random 메서드는 컴포넌트 측에 구현되어있다.

 

 

 

마지막으로 state의 Enabled에 false를 대입하여 이 시스템의 동작을 정지시킨다.

 

이게 없으면 매 프레임 spawn 처리를 반복하기에 꼭 멈추게 해주어야한다.

 

여기까지 설정하고 play 해보면 5000개의 엔티티가 생성되고 움직이는것을 볼 수 있다.

 

프로파일러로 부하를 확인해보자.

영상의 스펙에선 3.2ms 정도의 시간이 걸린다.

이정도의 시간이면 무거운 편은 아니지만 꽤 시간이 걸린다고 한다.

 

여기까지가 영상 5분정도까지의 내용이다.

 

최적화를 하는 내용은 다음시간에 하도록 하겠다.