[UE5] UObject

윤정민·2025년 2월 19일
0

Unreal Engine

목록 보기
35/35

UObject


언리얼은 게임 객체를 처리하기 위한 강력한 시스템을 가지고 있다.
언리얼의 객체에 대한 기본 클래스는 UObject이다.
UCLASS 매크로는 UObject처리 시스템이 이를 인식할 수 있도록 UObject에서 파생된 클래스에 태그를 지정하는 데 사용할 수 있다.

UCLASS


UClass 매크로는 언리얼 기반 타입을 설명하는 UCLASS에 대한 레퍼런스를 UObject에 제공합니다.
각 UClass는 클래스 디폴트 오브젝트(CDO, Class Default Object)라는 하나의 오브젝트를 유지합니다.
CDO는 기본적으로 클래스 생성자에 의해 생성되고 이후에는 수정되지 않는 디폴트 템플릿 오브젝트 입니다.

UCLASS와 CDO는 보토 읽기 전용으로 간주되어야 하지만, 주어진 오브젝트 인스턴스에 대해 얻을 수 있습니다.
오브젝트 인스턴스에 대한 UCLASS는 GetClass함수를 사용하여 언제든지 엑세스할 수 있습니다.

UCLASS에는 클래스를 정의하는 프로퍼티와 함수 세트가 포함되어 있습니다.
이는 표준 C++ 코드에 사용할 수 잇는 일반 C++함수 및 변수이지만, 오브젝트 시스템 내에서 행동하는 방식을 제어하는 언리얼 엔진 전용 메타데이터가 태그로 지정되어 있습니다.

UObject 클래스에는 UFUNCTION 또는 UPROPERTY 지정자로 리플렉션이 표시되지 않은 네이티브 전용 프로퍼티가 포함될 수 있습니다. 그러나 지정자 매크로로 표시된 함수와 프로퍼티만 해당 UCLASS 내에 나열됩니다.

프로퍼티 및 함수 타입

UObject는 모든 타입의 함수 또는 멤버 변수(프로퍼티라고도 함)를 가질 수 있습니다. 그러나 언리얼 엔진이 이러한 변수나 함수를 인식하고 조작하려면 특수 매크로로 표시하고 특정 타입 표준을 준수해야 합니다.

UObject 생성

UObject는 생성자 실행인자를 지원하지 않습니다. 모든 C++ UObject는 엔진 시작 시 초기화되며, 엔진은 디폴트 생성자를 호출합니다. 디폴트 생성자가 없으면 UObject가 컴파일되지 않습니다.
UObject 생성자는 가벼워야 하고 디폴트값과 서브오브젝트를 구성하는 데에만 사용되어야 하며, 생성 시 다른 함수 기능을 호출해서는 안 됩니다.
UObject는 런타임에 NewObject를 사용하거나 생성자의 경우 CreateDefaultSubobject를 사용하여 생성해야 합니다.

UObject는 절대로 new 연산자를 사용하면 안 됩니다. 모든 UObject는 언리얼 엔진으로 관리되는 메모리이며 가비지 컬렉션됩니다. new 또는 delete를 사용하여 메모리를 수동으로 관리하면 메모리가 손상될 수 있습니다.

언리얼 헤더 툴


UObject 파생 타입이 제공하는 기능을 활용하려면 해당 타입에 대한 헤더 파일에 전처리 단계를 실행하여 필요한 정보를 대조해야 합니다.
이 전처리 단계는 UnrealHeaderTool, 줄여서 UHT에서 수행합니다. UObject 파생 타입에는 준수해야 하는 특정 구조가 있습니다.

헤더 파일 포맷

소스(.cpp) 파일의 UObject 구현은 다른 C++ 클래스와 같지만, 헤더(.h) 파일의 정의는 언리얼 엔진에서 제대로 작동하려면 특정 기본 구조를 준수해야 합니다. 에디터의 New C++ Class 명령을 사용하는 것은 올바른 포맷의 헤더 파일을 구성하는 가장 쉬운 방법입니다. UObject 파생 클래스의 이름이 UMyObject이고 이 클래스가 생성된 프로젝트가 MyProject라고 할 때 UObject 파생 클래스의 기본 헤더 파일은 다음과 같습니다.

    #pragma once

	#include 'Object.h'
	#include 'MyObject.generated.h'

	UCLASS()
	class MYPROJECT_API UMyObject : public UObject
	{
		GENERATED_BODY()

	};

언리얼 관련 부분은 다음과 같습니다.

#include "MyObject.generated.h"

이 줄은 파일의 마지막 #include 지시문이 될 것입니다. 이 헤더 파일이 다른 클래스에 대해 알아야 하는 경우 해당 클래스를 파일의 어느 곳에서나 포워드 선언하거나 MyObject.generated.h 위에 포함할 수 있습니다.

UCLASS()

UCLASS 매크로는 언리얼 엔진에 UMyObject 가 표시되도록 합니다. 매크로는 클래스에 대해 어떤 기능을 켜거나 끌지 결정하는 다양한 클래스 지정자를 지원합니다.

class MYPROJECT_API UMyObject : public UObject

MyProject가 UMyObject 클래스를 다른 모듈에 노출시키기를 원한다면 MYPROJECT_API 를 지정해야 합니다. 이는 게임 프로젝트에 포함될 모듈이나 플러그인에 가장 유용하며 여러 프로젝트에 걸쳐 이식 가능하고 자체 포함된 함수 기능을 제공하기 위해 의도적으로 클래스를 노출합니다.

GENERATED_BODY()

GENERATED_BODY 매크로는 실행인자를 사용하지 않지만 엔진에 필요한 인프라를 지원하기 위해 클래스를 구성합니다. 모든 UCLASS 및 USTRUCT 에 필요합니다.

오브젝트 업데이트하기

티킹(Ticking)은 언리얼 엔진에서 오브젝트가 업데이트되는 방식을 말합니다. 모든 액터에는 프레임마다 티킹할 수 있는 기능이 있어 필요한 업데이트 계산이나 액션을 수행할 수 있습니다.

액터 및 액터 컴포넌트(ActorComponents)에는 등록 시 자동으로 호출되는 틱(Tick) 함수가 있지만, UObjects 에는 기본 업데이트 기능이 없습니다. 프로젝트에 필요한 경우 상속 클래스 지정자를 사용해 FTickableGameObject 클래스에서 상속하여 추가할 수 있습니다. 그런 다음 엔진이 각 프레임을 호출하는 Tick() 함수를 구현할 수 있습니다.

오브젝트 파괴하기

오브젝트가 더 이상 레퍼런스되지 않을 때 가비지 컬렉션 시스템이 자동으로 오브젝트를 파괴합니다. 즉, UPROPERTY 포인터, 엔진 컨테이너, TStrongObjectPtr 또는 클래스 인스턴스가 강한 참조를 가져서는 안 된다는 뜻입니다.

위크 포인터는 오브젝트가 가비지 컬렉션되는지 여부에 영향을 미치지 않습니다.

가비지 컬렉터를 실행하면, 참조되지 않은 오브젝트를 발견하면 메모리에서 제거합니다. 또한 MarkPendingKill() 함수를 오브젝트에서 바로 호출할 수 있습니다. 이 함수는 오브젝트에 대한 모든 포인터를 NULL 로 설정하고 글로벌 검색에서 오브젝트를 제거합니다. 오브젝트는 다음 가비지 컬렉션 패스에서 완전히 삭제됩니다.

스마트 포인터는 UObject와 함께 사용하기 위한 것이 아닙니다.

Object->MarkPendingKill()Obj->MarkAsGarbage() 로 대체되었습니다. 이 새로운 함수는 이제 오래된 오브젝트를 추적하는 용도로만 사용됩니다. gc.PendingKillEnabled=true 인 경우 PendingKill 로 표시된 오브젝트는 자동으로 null이 되고 가비지 컬렉터에 의해 삭제됩니다.

강한 참조가 있으면 UObject가 유지됩니다. 이러한 레퍼런스가 UObject를 활성 상태로 유지하는 것을 원하지 않는 경우 해당 레퍼런스가 위크 포인터를 사용하도록 변환하거나 (퍼포먼스가 중요한 경우) 프로그래머가 수동으로 삭제하는 노멀 포인터여야 합니다.

profile
그냥 하자

0개의 댓글

관련 채용 정보