< Unreal Object (UObject) >
- 접두사를 사용하여 구분
- F (일반 C++오브젝트) : 저수준의 빠른 처리를 위한 기능 구현에 사용 (일반 C++에서 사용하는 네이티브 객체)
- U (언리얼 오브젝트) : 콘텐츠 제작에 관련된 복잡한 설계 구현에 사용 (언리얼 엔진의 관리를 받는 객체)
- 언리얼 엔진의 모든 객체들은 UObject를 파생함
- UObject가 제공하는 여러 기능들(Reflection 생성, GC, CDO, etc.)을 통해 언리얼 엔진은 객체가 실행되는 세계를 구축 가능
- 언리얼 객체의 기본이 되는 시스템
- 언리얼 엔진의 일반적인 클래스들의 최상위 클래스
- 언리얼 엔진 실행 환경에 의해 관리되는 특수한 C++ 객체
- 언리얼 엔진에서 항상 모듈 단위로 관리됨
- 언리얼 엔진에서 오브젝트에 대한 Base Class는 UObject이다.
- UObject를 상속받은 클래스는 언리얼이 제공하는 관리 시스템의 이점을 모두 누릴 수 있다
- UCLASS 매크로는 UObject에서 파생된 클래스에 태그를 지정하여 UObject 처리 시스템이 인식하도록 할 수 있다
- UObject는 언리얼 엔진이 자체적으로 만들어 제공하는 프레임웍이므로, 일반적인 방법으로는 만들 수 없고, UHT의 도움을 받아야 함
- 헤더 파일에서 클래스를 UObject 규격에 맞게 선언하면, 바로 컴파일 하는 것이 아니라 언리얼 헤더 툴이 이를 파싱하고 분석함
- 헤더 파일의 선언이 규격에 맞지 않으면 UHT에 의해 에러가 발생되고,
- 규격에 맞게 선언했다면 UHT는 부가적인 메타 정보를 담은 소스코드를 프로젝트의 Intermediate 폴더에 생성
- 이 작업이 모두 끝나면, 본격적으로 컴파일을 진행
< UObject 가 필요한 이유 >
- 모든 것이 추적 가능 : 통합된 기본 클래스인 UObject를 사용하면, 파생된 모든 객체를 추적 가능
- 상속 메커니즘 : Equals, Clone, GetHashCode, ToString, GetName, GetMetaData 등 모든 객체에 적용하려는 속성과 인터페이스를 추가 가능
- 메모리 관리 : Reference Count를 UObject에 추가시켜, 관리하기 용이하게 함. 이를 통해 GC는 Reference Count에서 AddCount(), ReleaseCount() 같은 함수를 만들어두고 체크만 하면 됨. GC방식을 사용하면 참조할 통일된 객체를 갖게 되므로, 현재의 GC를 지원하는 대부분의 언어는 이와 같이 디자인하게 됨
- Serialization : 서로 다른 타입에 대한 직렬화를 지원하려면, 각 타입에 대해서 별도의 방법을 작성하거나, 템플릿 같은 곳에서 태그를 사용해야 함. 통합되어 있다면 Reflection이나 CDO에 의해 직렬화를 편하게 할 수 있음
- 통계 : 예를 들어, 어떤 객체가 가장 많이 할당되었는지, 어떤 객체가 가장 오래 할당되었는지 등을 확인 가능. 통일된 인터페이스 때문에 추적이 용이하고 편리한 다른 기능도 쉽게 구현 가능
- 디버깅 편의성 : 통일된 Object가 있기에, 어떤 객체 때문에 문제가 발생했는는지 확인이 쉬움
< UObject 특징 >
- CDO(Class Default Object / 클래스 기본 객체) : 오브젝트의 초기값을 자체적으로 관리
- Reflection(프로퍼티 시스템) : 런타임에서 클래스 정보 참조 가능
- Interface : 모던 객체 지향 언어가 제공하는 인터페이스 제공
- 향상된 열거형 : 보다 향상된 열거형 지원
- Delegate : 객체간의 의존성을 낮출 수 있게, 함수를 묶어서 효과적으로 관리 및 호출
- Garbage Collection : 자동 메모리 관리
- Struct(향상된 구조체) : 리플렉션이 가능한 구조체 지원
- Serialization(직렬화) : 객체 정보를 바이트 스트림으로 저장, 전송, 불러들이는 기능 (오브젝트 정보를 안전하게 관리)
- Editor Integration : 언리얼 에디터의 인터페이스를 통해 값을 편집 가능
< 스크립트 >
- 필수 헤더 2가지 : CoreMinimal.h , UObject/NoExportTypes.h
- UCLASS() : 언리얼 오브젝트 선언임을 명시하기 위한 매크로
- 대문자로프로젝트이름_EX_API : xx라는 언리얼오브젝트를 다른 DLL에서도 사용할 수 있도록 개방해주는 코드. 이걸 없애면 다른 모듈에서 참조하지 못하고 언리얼오브젝트라는 모듈 내에서만 사용가능해짐.
< 언리얼 오브젝트 선언 규칙 >
- 클래스이름.generated.h 가 반드시 맨 아래에 include 되어 있어야 함
- 클래스 선언 전에 UCLASS 매크로 선언
- 접두사(액터A, 오브젝트U, 위젯S)
- UObject 클래스는 언리얼 오브젝트 최상단에 위치한 기본 클래스이며, 이를 상속받은 클래스는 모두 UObject임
- 클래스 내부에 GENERATED_BODY() 매크로 선언
- 모듈이름_API : 상황에 따라 부가 설정을 해주는 매크로
- 언리얼 오브젝트의 생성자는 오브젝트의 기본값을 지정하는데 사용됨. CDO 생성 시, 이 생성자 코드가 한 번 실행됨
- 멤버 변수 위에 UPROPERTY() 매크로를 얹어주면, 이 변수는 앞으로 언리얼 엔진의 관리를 받게 됨
- 멤버 함수 위에 UFUNCTION() 매크로를 얹어주면, 블루프린트와 연동되게 할 수 있으며, 델리게이트나 리플리케이션과 같은 함수를 사용할 수 있어서 활용폭이 늘어남
< 언리얼 오브젝트의 구성 >
- 언리얼 오브젝트에는 특별한 프로퍼티와 함수를 지정 가능
- 언리얼 시스템에 의해 관리되는 클래스 멤버 변수에는 UPROPERTY라는 매크로를 지정
- 언리얼 시스템에 의해 관리되는 클래스 멤버 함수에는 UFUNCTION라는 매크로를 지정
- 이 매크로들에는 에디터와 연동되는 메타데이터를 심을 수 있음
- 모든 언리얼 오브젝트는 클래스 정보(를 담은 UCLASS)와 함께 함. UCLASS를 사용하여 자신이 가진 프로퍼티와 함수 정보를 컴파일 타임과 런타임에서 조회 가능
< 언리얼 오브젝트에서 헤더의 위치 >
- 헤더파일의 헤더 순서 : “--.generated.h”파일이 항상 가장 밑에 있어야 함
- 다른 헤더를 추가할 때는 이 헤더 위쪽에 추가하기
- 다른 헤더를 추가할 때는 이 헤더 위쪽에 추가하기
- cpp파일의 헤더 순서 : 해당 오브젝트의 헤더가 가장 위쪽에 위치해야 함
- 다른 오브젝트의 헤더가 현재 구현하고자하는 언리얼 오브젝트의 헤더보다 위에 위치하면 컴파일 에러 발생
< 언리얼 오브젝트 생성 시점 >
- C++에서 UObject를 생성하는 시점은 NewObject() 메소드를 통해 새로운 인스턴스를 만들 때임
- NewNamedObject(), ConstructObject() 등의 메소드를 사용하기도 함
- 새로운 UObject를 인스턴싱 한다는 점에서 용도는 동
< 언리얼 오브젝트 삭제 시점 >
- 명시적으로 파괴 메소드를 사용했을 때 ( ex. Actor::Destroy() )
- 해당 오브젝트가 더 이상 강참조되지 않을 때, 가비지 컬렉터에 의해 자동으로 삭제됨
- Level이 사라질 때, 해당 Level에서 참조하는 오브젝트들이 삭제됨
- 레벨은 가비지 콜렉팅 항목에서 언급했던 Root 역할을 담당한다고 보면 됨
- Root가 사라졌으므로, 해당 Root에 연결되어 있던 오브젝트들이 삭제되는 것
'Base > Unreal C++' 카테고리의 다른 글
Reflection (0) | 2024.07.03 |
---|---|
CDO (Class Default Object) (0) | 2024.07.03 |
문자열 (0) | 2024.07.03 |
Assert (0) | 2024.07.02 |
Log 출력 (0) | 2024.07.02 |