게임 개발/언리얼 5

언리얼5 - 리플렉션을 활용하는 언리얼 에디터 UI와 UI의 확장

싹난 감자 2024. 12. 19. 22:06

 

언리얼 에디터 UI

언리얼 에디터는 런타임 또는 디자인 타임에 클래스, 속성, 메서드 정보를 활용하여 자동으로 에디터의 UI를 생성하거나 확장하는 작업을 지원함.

개발자가 직접 특성 클래스를 수정하지 않아도 리플렉션을 통해 자동으로 타입과 속성 정보를 읽고, 이를 바탕으로 UI를 동적으로 생성하거나 관리할 수 있음.

 

언리얼의 리플렉션 시스템은 UCLASS, UPROPERTY, UFUNCTION 등을 통해 타입과 속성 정보를 메타 데이터로 저장.

이를 기반으로 속성 패널(Details Panel), 블루프린트 노드, UI 확장 등을 자동으로 생성할 수 있음.

 

1. 리플렉션을 활용한 Details Panel 생성

UCLASS와 UPROPERTY를 사용해 속성을 정의하면 언리얼 리플렉션 시스템이 이를 읽고 Details Panel에 자동으로 UI를 생성함.

UCLASS(Blueprintable)
class UMyCharacter : public UObject
{
    GENERATED_BODY()

public:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stats")
    float Health;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stats")
    float Stamina;
};

사용자가 Details Panel에서 값을 변경하면 리플렉션을 통해 런타임 객체에 변경 사항이 즉시 반영됨.

 

2. 리플렉션을 활용한 블루프린트 확장

UFUNCTION으로 정의한 함수는 리플렉션 시스템에 등록되어 블루프린트 에디터에서 자동으로 노드로 사용할 수 있게 됨.

UCLASS()
class UMyBlueprintLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable, Category="MyCategory")
    static void PrintCustomMessage(const FString& Message);
};

UFUNCTION 정보(함수명, 매개변수, 반환 값)을 읽어 블루프린트에 노드로 추가, 함수 수정 시 자동으로 UI가 갱신됨.

 

3. 플러그인 또는 커스텀 위젯 확장

플러그인이나 런타임에서 사용자 정의 속성 또는 객체를 자동으로 UI에 반영할 수 있음.

언리얼 리플렉션 시스템이 클래스와 그 속성 정보를 읽어들여 커스텀 속성을 에디터 UI에서 볼 수 있도록 Details Panel을 확장하거나, Property Editor Module을 통해 새 UI를 추가할 수 있음.

 

유니티와의 차이점

유니티는 리플렉션 기반 시스템보다는 컴포넌트와 데이터 중심 설계로 동적 UI를 구현함

기준 Unity 에디터의 동적 UI 언리얼 에디터의 리플렉션 기반 UI
UI 구성 방식 컴포넌트 기반, 코드 또는 Inspector 설정 메타데이터 기반으로 런타임/디자인 타임 자동화
동적 동작 코드로 생성/수정 리플렉션으로 자동 동작 생성 및 속성 관리
확장성 개발자가 모든 로직을 명시적으로 작성해야 함 메타 데이터로 추가 동작과 에디터 UI 확장이 쉬움
자동화 수준 수작업이 많음 자동화된 UI 생성 및 관리
데이터 바인딩 지원 외부 플러그인(Ex: MVVM 패턴, 데이터 바인딩) 필요 리플렉션 기반 속성 접근으로 기본 지

 

 

 

 

 

UI 확장(작업 툴 제작)

언리얼의 리플렉션과 메타 데이터 시스템 덕분에 툴 제작에 유리함.

특정 클래스나 속성을 에디터에 노출하려면 UPROPERTY를 사용하면 됨.

 

UPROPERTY 매크로 지정자

4개까지 지정할 수 있음

 

1. Transient 키워드

언리얼 오브젝트는 직렬화가 가능. 오브젝트의 UPROPERTY 속성을 저장하고 로딩할 수 있으나

게임이 실행될 때마다 매번 변경되는 값의 경우 그 값을 보관하는 것은 의미가 없고 디스크 공간을 낭비하게 됨.

Transient 키워드를 추가하면 해당 속성을 직렬화에서 제외할 수 있음.

 

2. 편집 관련

 

  • BlueprintReadWrite : 블루프린트에서 읽고 쓰기 가능
  • BlueprintReadOnly : 블루프린트에서 읽기만 가능
  • Edit : 편집 가능
  • Visible : 보여줄 것인지
  • DefaultsOnly : 아키타입(원형)에서만
  • InstanceOnly : 인스턴스에서만
  • Anywhere : 어디에서나

EditDefaultsOnly, VisibleAnyWhere 등

 

블루프린트를 사용하면 '오브젝트의 원형'을 에디터에서 볼 수 있다. 그리고 이 원형을 실제 맵에 배치한 것이 인스턴스.

 

3. 카테고리

Category=" "

디테일 패널의 항목 이름을 명명할 수 있음.

문자열로 처리되어 ""로 감싸야함. 한 단어까지는 큰 따옴표를 사용하지 않아도 인식되지만 두 단어 이상(띄어쓰기)이라면 큰따옴표가 있어야 정상적으로 동작됨

 

4. 메타(meta) 태그

AllowPrivateAccess : private으로 선언된 언리얼 오브젝트 객체들을 블루프린트에서도 접근할 수 있게 함

OOP(Object-Oriented Programming) 설계를 따르면서 변수에 접근이 가능해짐.

에디엍에서 편집이 가능함과 동시에 변수 데이터를 은닉할 수 있게 되어 캡슐화가 가능

 

- ClampMin, ClampMax, UIMin, UIMax  등의 메타 태그로 Details Panel에서 프로퍼티 값의 범위를 정하거나 슬라이더나 툴팁 등을 커스터마이징 가능

 

 

 

Custom Editor Widgets

FPropertyEditorModule을 사용해 완전히 커스텀한 패널과 도구를 제작할 수도 있음.

블루프린트 함수, 머티리얼 노드 등도 리플렉션 기반으로 동작하므로 개발자 정의 동작과 쉽게 연결이 가능.

 

데이터 드리븐 툴 제작

CSV 파일을 불러와 자동으로 설정하는 툴을 제작할 수 있음.

UPROPERTY로 데이터를 바인딩하거나 FEditorUtilityWidget을 활용해 UI를 생성.

UPROPERTY(EditAnywhere, Category = "Character Stats")
FString CharacterName;

UPROPERTY(EditAnywhere, Category = "Character Stats")
float Health;

UFUNCTION(CallInEditor, Category = "Character Stats")
void ImportFromCSV();