Unreal

[Unreal5] UObject와 Reflection

usingsystem 2024. 5. 22. 21:45
728x90

https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/ProgrammingWithCPP/UnrealArchitecture/Objects/

 

오브젝트

기본 게임플레이 요소인 Actor 와 Object 에 대한 설명입니다.

docs.unrealengine.com

 

UObject

UObject를 상속 받으면 Reflection System에 의해 UHD가 실행되어 Uclass 객체를 만들어주고 Uclass 객체 내부에 CDO라는 객체 샘플 사본을 하나 만들어 두 개가  준비가 되게하여 메모리를 관리한다.

 

UObject는 언리얼 엔진의 대부분의 객체 유형의 기본 클래스로 언리얼의 모든 오브젝트는 UObject를 상속받는다. 

Uobject를 상속받은 오브젝트를 객체로 만들면 메모리관리를 Unreal에서 제공하는 GC에서 할 수 있게된다.  하지만 일반적으로 객체를 만들 때 일반 포인터로 만드는 것 이 아닌 NewObject키워드를 사용하여 만들어야 자동으로 메모리관리를 해주게 되어 delete를 따로 해주지 않아도된다.

하지만 객체를 만들 때 리플랙션(UPROPERTY, UFUNCTION 등)과 함께 선언하지 않으면 아무리 NewObject를 사용하여 객체를 만들었다고 하더라도 GC가 메모리를 비워버린다. UPROPERTY 등을 사용하면 샘플견본 같은 걸 만들어놓기 때문에 GC가 비어있다고 판단하지 않는다.

  1. 메모리 관리: UObject는 언리얼 엔진의 가비지 컬렉션 시스템과 통합되어 있어 메모리를 자동으로 관리합니다.
  2. Reflection 지원: Reflection 시스템의 일부로, UObject는 런타임 타입 정보 및 동적 동작을 허용합니다.
  3. 생명주기: UObject는 생성, 초기화, 파괴를 포함한 명확한 생명주기를 가지고 있습니다. BeginDestroy와 FinishDestroy 같은 훅을 통해 커스텀 동작을 정의할 수 있습니다.
UCLASS()
class MYGAME_API UMyObject : public UObject
{
    GENERATED_BODY()

public:
    UMyObject();

    UPROPERTY() //리플랙션
    FString MyString;

    UFUNCTION()//리플랙션
    void MyMethod();
};

// 생성자와 메서드의 구현
UMyObject::UMyObject()
{
    MyString = TEXT("Hello, Unreal!");
}

void UMyObject::MyMethod()
{
    UE_LOG(LogTemp, Warning, TEXT("MyMethod called!"));
}
  • UMyObject가 UObject를 상속받아 기본 클래스의 모든 기능을 활용합니다.
  • UPROPERTY 매크로를 사용하여 MyString을 Reflection 시스템에 노출합니다.
  • UFUNCTION 매크로를 사용하여 MyMethod를 Reflection 시스템에 노출하여 블루프린트 및 기타 런타임 콘텍스트에서 호출할 수 있게 합니다.

https://www.unrealengine.com/ko/blog/unreal-property-system-reflection

 

 

언리얼 엔진의 Reflection 시스템

일반 C++ 오브젝트를 언리얼 오브젝트(UObject)로 만들기 위해 리플렉션(Reflection)을 활용한다. 리플렉션이 있는 오브젝트는 런타임에 자기 자신을 조사하여 객체를 검사하고 수정할 수 있는 기능을 제공한다.

오브젝트가 리플렉션을 가지면 디테일 패널, 직렬화(Serialization), 가비지 컬렉션, 네트워크 리플리케이션, 블루프린트 등 언리얼 엔진의 유용한 시스템에서 사용될 수 있다.

리플렉션을 가지게 하려면 오브젝트가 포함된 C++ 클래스 헤더 파일에 "모듈명".generated.h 헤더를 포함해야 한다. 해당 헤더를 가져야 리플렉션이 있는 시스템에서 해당 클래스를 고려해야 하고 시스템 구현이 필요함을 언리얼 헤더 툴 UHT(Unreal Header Tool)에 알린다.

 

UField

  • UClass, UFunction, UProperty 같은 여러 메타 데이터 클래스들의 공통 기반 클래스입니다. UField는 주로 객체의 필드(변수, 함수 등)에 대한 메타 데이터를 저장합니다.

UStruct

  • 언리얼 엔진에서 구조체를 나타내는 기본 클래스입니다. 구조체는 데이터와 함수의 집합을 포함할 수 있는 객체 유형입니다.

UClass (C++ class)

  • 언리얼 엔진의 클래스 시스템을 나타내는 클래스입니다. 모든 UObject 기반 클래스는 UClass를 통해 리플렉션 됩니다.
  • GENERATED_BODY() 매크로를 사용하여 리플렉션 시스템과 통합합니다.

UScriptStruct (C++ struct)

  • 언리얼 엔진의 스크립트 구조체를 나타내는 클래스입니다. C++의 struct와 비슷하지만, 언리얼의 리플렉션 시스템에서 사용되기 위해 특별히 확장된 것입니다.

UFunction (C++ function)

  • 클래스의 멤버 함수에 대한 정보를 관리합니다. 함수의 이름, 반환형, 매개변수, 접근 제어자 등 함수의 특성을 정의합니다. 런타임에 함수 호출, 이벤트 바인딩 등에 사용됩니다.

UEnum (C++ enumeration)

  • 열거형의 각 항목과 관련된 메타 데이터를 관리합니다. 열거형의 이름과 값들을 정의하고, 블루프린트나 기타 언리얼 시스템에서 사용할 수 있도록 합니다.

UProperty (C++ member variable or function parameter)

  • 변수나 매개변수의 메타 데이터를 관리합니다. 변수의 이름, 타입, 접근 제어자, 초기 값 등을 정의합니다. 런타임에 변수의 값을 읽거나 쓰는 작업에 사용됩니다.
UCLASS()
class MYGAME_API AMyActor : public AActor
{
    GENERATED_BODY()

public:
    // UPROPERTY를 사용하여 변수를 Reflection 시스템에 노출
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyCategory")
    int32 MyProperty;

    // UFUNCTION을 사용하여 함수를 Reflection 시스템에 노출
    UFUNCTION(BlueprintCallable, Category = "MyCategory")
    void MyFunction();
};

 

Reflection과 Property Specifiers

https://docs.unrealengine.com/4.27/ko/ProgrammingAndScripting/GameplayArchitecture/Properties/Specifiers/

 

프로퍼티 지정자

엔진 및 에디터의 다양한 면에 대한 프로퍼티 작동방식을 지정하기 위해 UProperty 를 선언할 때 사용되는 키워드입니다.

docs.unrealengine.com

속성 지정자(Property Specifiers)를 통해 에디터상에 노출 및 블루프린트에 읽기, 쓰기를 제어하고 카테고리를 달 수 있는 등 다양하게 활용할 수 있습니다.

UCLASS()
class MYGAME_API AMyPlayer : public ACharacter
{
    GENERATED_BODY()

public:
    AMyPlayer();

    // 플레이어의 건강 상태를 나타내는 변수로, 블루프린트에서 읽기 및 쓰기 가능하며, 네트워크에서 복제됩니다.
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category="Stats")
    int32 Health;

    // 플레이어의 이름을 나타내는 변수로, 블루프린트에서 읽기 가능하고, 에디터의 기본값 속성 창에서 편집 가능.
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Stats")
    FString PlayerName;

    // 플레이어의 현재 무기를 나타내는 변수로, 네트워크에서 복제될 때 OnRep_CurrentWeapon 함수를 호출함.
    UPROPERTY(ReplicatedUsing=OnRep_CurrentWeapon, VisibleAnywhere, Category="Equipment")
    AWeapon* CurrentWeapon;

    // CurrentWeapon 변수의 변경을 처리하는 함수.
    UFUNCTION()
    void OnRep_CurrentWeapon();
};
728x90