개발자 면접 공부/언리얼 엔진

언리얼 엔진의 CDO 로딩 과정 등

chogyujin 2023. 1. 31. 22:21
728x90

이번포스팅에는 언리얼의 초기화 과정 즉 CDO 로딩 과정을 공부하도록 하겠습니다.

 


1. 개요

언리얼 엔진에서의 C++ 상에 생성자는 constructHelpers라는 키워드를 사용하여 애셋이나 컴포넌트 등을 불러올수가 있고 붙힐수도 있습니다.

여기서 의문점이 들수밖에없습니다. 왜 언리얼 엔진은 각각의 생성자에 저런 특수한 키워드를 사용할수있으며 왜 begin play나 다른 함수에는 사용이 불가한가에 대해서

이를 통해 공부를 하였고 포스팅을 해볼려고 합니다.

 


2. UClass, 리플렉션, 프레임워크

UClass에는 언리얼 오브젝트에 대한 클래스 계층 구조 정보와 맴버 변수, 함수에 대한 정보를 모두 기록

 

언리얼 엔진은 하나의 오브젝트가 만들어지기 위해서는, 실제 컴파일 전에 언리얼 헤더 툴에 의해 헤더 파일을 분석하는 과정이 선행됩니다.

이 과정이 완료되면 Intermediate 폴더에 언리얼 오브젝트의 정보를 담은 메타 파일이 생성이 됩니다.

 

메타 소스 파일과 헤드 파일을 생성하는 목적은 여러가지 있지만 C++문법에서 제공하지 못하는 런타임에서의 빠른 클래스 정보의 검색을 하기위해 있습니다.

 

이 메타 정보는 언리얼 엔진이 지정한 UClass라는 특별한 클래스를 통해 보관됩니다.

 

UClass에는 언리얼 오브젝트에 대한 클래스 계층 구조 정보와 맴버 변수, 함수에 대한 정보를 모두 기록하고있습니다.

 

하지만 단순히 검색하는 것에서 더 나아가, 런타임에서 특정 클래스를 검색해 형(Type)을 알아내
인스턴스 맴버 변수 값을 변경하거나 특정 인스턴스의 맴버 함수를 호출하는 것이 가능합니다.

 

이러한 기능을 리플렉션이라고 부르며 C++에서는 제공을 안해주지만 언리얼 엔진 자체적으로 프레임 워크를 만들어 제공합니다.


3. 클래스 기본 객체 (CDO)

컴파일 단계에서 언리얼 오브젝트 마다 UClass가 생성된다면,

 

실행 초기의 런타임 과정에서는 언리얼 오브젝트마다 클래스 정보와 함께 언리얼 오브젝트 인스턴스가 생성됩니다.

 

이 특별한 인스턴스는 언리얼 오브젝트의 기본 세팅을 지정하는데 사용하는데,

이를 클래스 기본 객체(Class Default Object) 줄여서 CDO라고 합니다.

 


4. CDO?

언리얼 엔진에서 CDO를 만드는 이유는 언리얼 오브젝트를 생성할 때마다 매번 초기화 하지말고

기본 인스턴스를 미리 만들어 놓고 복제하는 방식으로 메커니즘이 구성이 되있기 때문입니다.(아마 오브젝트 폴링인거 같습니다.)

 

하나의 언리얼 오브젝트가, 작을경우에는 매우 상관이 없지만, 엉청 커져버리면 초기화 생성 작업이 매우 비용이 많이 들기 때문입니다.

 

그래서 큰 기본 객체 덩어리를 복제한 후 속성 값만 변경하는 방법을 사용합니다.

 

하나의 언리얼 오브젝트가 초기화 될 때에는 두 개의 인스턴스가 항상 생성됩니다.

 

출처 : https://kyoun.tistory.com/125

이러하게 언리얼 오브젝트는 언리얼 엔진에서 항상 모듈 단위로 관리됩니다.

언리얼 에디터를 띄우면 초기화라는 문구 옆에 %가 증가하는 것을 볼 수 있는데,

대부분의 과정이 에디터에 사용할 모듈들을 로딩하는데에 사용됩니다.

 

또한, 생성자에 굳이 constructHelpers를 사용하는 이유는 만약 begin이나 다른곳에 만들어서 사용하면
언리얼 에셋은 경로를 지정해서 불러오는 작업을 하는데 만약 에셋경로가 잘못되거나 컴포넌트가 잘못 붙혀지기라도 하면
실행중에 펑 터지는 결과를 얻을수 있어 미리 CDO를 생성해 생성자를 호출하고 초기화를 하는 작업을 통해 맞는 경로인지 확인하고 맞다면 정상적으로 동작하게 하는 안전성도 있습니다.

 


5. 결론

1. 리플렉션에 대해서 자세히 다시 포스팅 할 예정 (지금은 실행시간 도중에 객체에 정보 맴버 변수 함수의 정보 등을 알수있다 정도)

2. CDO를 미리 생성하여 생성자를 부르고 초기화 한다. 이유는 오브젝트들을 실행시 연속으로 부르기에는 너무 비용이 크다

3. 또한, 이렇게 생성자에만 쓸수있는 함수들은 경로상을 물어보는 경우가 많고 컴포넌트등을 붙여야하는 작업이있기 때문에 안전을 위해 미리 생성자를 통해 검사


6. Ref

https://kyoun.tistory.com/125

 

4. 클래스 기본 객체 (CDO) + 로딩과정 + 로그디버깅 + 인스턴스생성

이번 강좌에서는 하나의 모듈에서 다른 모듈을 참조하는 기능을 구현해보겠습니다. 모듈간의 참조를 구현하기 위해서는 우선 언리얼 오브젝트의 초기화 과정에 대한 이해가 필요합니다. UCLASS,

kyoun.tistory.com