언리얼 - 엔진 11 : 언리얼 리플렉션 시스템

김정환·2025년 4월 10일
0

Unreal Engine

목록 보기
12/24

1. BP vs C++ 개발

🧩 Blueprint (BP)

시각적 스크립팅 도구
노드를 연결하여 게임 로직을 구성하며, 비개발자나 프로토타이핑에 적합.

✅ 장점

  • 수정 후 즉시 실행 가능 (빌드 불필요)
  • 직관적인 노드 기반 구성
  • 디자이너도 접근 가능

❌ 단점

  • 규모가 커질수록 노드 관리가 어려움
  • 결국 C++ 기반이므로 성능 병목 가능
    (ex. 리얼타임 연산, AI 등)

⚙️ C++

언리얼 엔진의 핵심 언어
고성능, 확장성 있는 시스템 개발에 유리.

✅ 장점

  • 엔진 코어까지 커스터마이징 가능
  • 외부 라이브러리 연동 유리
  • 대규모 프로젝트에 적합
  • 정밀한 메모리 제어 가능

❌ 단점

  • 진입 장벽 높음
  • 빌드 과정 번거로움

🔁 상호보완적 사용

현업에서는 BP + C++ 병행 사용이 일반적.

역할사용 도구
빠른 UI 구성 / 간단 이벤트 / 시각 효과BP
성능 요구 / 복잡한 연산 / 시스템 확장C++

☑️ 하이브리드 워크플로우로 각 도구의 강점을 조합하여 개발


2. 리플렉션 시스템 Reflection System

C++ 클래스의 변수 및 함수 정보엔진 내부의 메타데이터 형태로 저장하고,
이를 에디터나 블루프린트에서 활용할 수 있게 만들어주는 기술

C++ 클래스에 있는 여러 멤버를 “Reflectoin (반사)”해
에디터와 블루프린트에서 직접 설정, 호출이 가능하도록 함.

주요 기능

  • 프로그래머가 만든 코드를 디자이너나 기획자가 직관적으로 조정 가능
  • 매개변수 에디터에서 바로 조정 (슬라이더나 숫자 입력)하여 반복 테스트를 빠르게 진행 가능

사용

  • 코드에서만 조정하던 매개변수를 에디터에서 바로 수정 가능
    • 슬라이더, 숫자 입력 등 UI 제공
  • 값 수정 후 반복 테스트가 빠르고 효율적

3. C++ 클래스 리플랙션 등록

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Item.generated.h" // 반드시 마지막에 위치해야 합니다.

UCLASS()
class SPARTAPROJECT_API AItem : public AActor
{
		GENERATED_BODY()
	
public:	
		AItem();
	
protected:
		USceneComponent* SceneRoot;
		UStaticMeshComponent* StaticMeshComp;
	
		float RotationSpeed;
	
		virtual void BeginPlay() override;
		virtual void Tick(float DeltaTime) override;
};
  • #include "Item.generated.h"
    • 언리얼 엔진이 자동 생성하는 헤더 파일.
    • 클래스의 리플렉션 및 엔진 통합에 필요한 코드가 포함.
    • 헤더들 중 반드시 마지막에 있어야 함.
      • 순서가 바뀌면 빌드 에러가 발생할 수 있음.
  • UCLASS()
    • 해당 클래스를 언리얼 엔진의 리플렉션 시스템에 등록한다는 의미
    • 이 매크로가 있어야만 블루프린트 등 에디터 차원에서 이 클래스를 인식하고 사용 가능
  • GENERATED_BODY()
    • UCLASS()와 쌍으로 사용하는 매크로
    • 언리얼의 코드 생성 도구가 사용하는 코드를 삽입하는 역할
    • 클래스 내부에 필요한 리플렉션 정보를 자동으로 생성

UCLASS() 매크로 주요 지정자

클래스를 리플렉션 시스템에 등록하면서 추가적으로 몇 가지 옵션 (지정자)을 설정 가능

기본 동작

UCLASS()
class SPARTAPROJECT_API AItem : public AActor
  • 옵션을 주지 않으면 Blueprintable, BlueprintType 옵션을 기본값으로 설정

주요 옵션

  • Blueprintable : BP에서 상속 가능한 클래스로 설정
  • NotBlueprintable : BP에서 이 클래스를 상속할 수 없도록 설정
  • BlueprintType
    • BP에서 변수나 참조로 사용할 수 있게 설정
    • 이 옵션만 있으면, 상속은 허용되지 않고 참조만 가능

4. 변수에 리플랙션 등록

UPROPERTY() 매크로 주요 지정자

UPROPERTY()에 여러 지정자를 사용해서 변수에 대한 에디터 표시를 상세하게 설정 가능.
다음은 자주 쓰는 대표적인 지정자들.

1. 편집 가능 범위 지정자

  • VisibleAnywhere: 읽기 전용으로 표시되며, 수정은 불가능
  • EditAnywhere: 클래스 기본값, 인스턴스 모두에서 수정 가능
  • EditDefaultsOnly: 클래스 기본값에서만 수정 가능
  • EditInstanceOnly: 인스턴스에서만 수정 가능

2. BP 접근성 지정자

  • BlueprintReadWrite: Blueprint 그래프에서 Getter/Setter로 값을 읽거나 쓸 수 있습니다.
  • BlueprintReadOnly: Blueprint 그래프에서 Getter 핀만 노출되어, 읽기만 가능합니다.

3. Category 지정자

여러 변수를 비슷한 카테고리에 묶어, 세부 정보 패널에서 깔끔하게 정리 가능

private:
	UPROPERTY(EditAnywhere, Category = "Platform|Movement")
	FRotator Velocity;

  • 디테일에 다음과 같이 하나의 묶음으로 표시됨.
  • "Platform|Movement" : Platform 카테고리 내에 Movement라는 하위 카테고리에 저장.

4. 메타 옵션 지정자

  • meta=(ClampMin="0.0"): 에디터에서 변수 입력 시 최소값을 제한할 수 있음
  • meta=(AllowPrivateAccess="true"): 해당 멤버가 private로 선언되어 있어도, 에디터나 BP에서 접근할 수 있도록 허용.

만약 UPROPERTY()만 있고, 추가 지정자를 하나도 주지 않는다면?

  • 엔진 리플렉션 시스템에는 등록되지만, 에디터나 BP에 노출되지는 않음.
    • 엔진은 변수의 존재를 알고 있지만, 외부에는 보이지 않도록 숨긴 상태.
  • 리플렉션에 등록만 되어 있어도 가비지 컬렉션(메모리 관리)과 직렬화(세이브/로드) 같은 엔진 내부 기능이 작동할 수 있음.

예시

protected:
		// Root Scene Component, 에디터에서 볼 수만 있고 수정 불가
		UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Item|Components")
		USceneComponent* SceneRoot;	
        
		// Static Mesh, 에디터와 Blueprint에서 수정 가능
		UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Item|Components")
		UStaticMeshComponent* StaticMeshComp;
	
		// 회전 속도, 클래스 기본값만 수정 가능
		UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Item|Properties")
		float RotationSpeed;
  • 리플렉션에 등록해두면 BP 클래스로 만들었을 때 변수를 디테일에서 조정할 수 있음.
  • 변수를 바꿀 때 코드 수정해서 빌드하지 않고 에디터에서 바로 바꿀 수 있는 것.

5. 함수에 리플랙션 등록

함수 또한 블루프린트에서 직접 호출할 수 있도록 등록할 수 있음.
복잡한 C++ 로직을 BP에서 간단한 노드로 불러와 제어할 수 있으므로 작업 효율이 높아짐.
UFUNCTION() 매크로를 사용해서 등록.

UFUNCTION() 매크로 주요 지정자

BP 관련 지정자

  • BlueprintCallable
    • BP 이벤트 그래프(노드)에서 호출(Execute) 가능한 함수로 설정
  • BlueprintPure
    • Getter 역할만 수행 (Exec 핀 없이 Return Value만 노출)
  • BlueprintImplementableEvent
    • 함수의 선언만 C++에 있고, 구현은 BP에서 하도록 합니다.
    • C++ 코드에서는 함수 이름만 정의하고,
      실제 동작은 Blueprint Event Graph 안에서 이벤트 노드처럼 구현.

만약 UFUNCTION()에 지정자를 하나도 쓰지 않았다면?

  • UPROPERTY()와 마찬가지로 언리얼 리플렉션에 등록되긴 하지만 BP에 노출되지는 않음.
  • 엔진이 함수의 존재는 파악하되, BP에서 직접 호출할 수 없게 숨겨둔 상태

예시

protected:
    // 함수를 블루프린트에서 호출 가능하도록 설정
    UFUNCTION(BlueprintCallable, Category="Item|Actions")
    void ResetActorPosition();
		
	// 블루프린트에서 값만 반환하도록 설정
    UFUNCTION(BlueprintPure, Category = "Item|Properties")
    float GetRotationSpeed() const;

	// C++에서 호출되지만 구현은 블루프린트에서 수행
    UFUNCTION(BlueprintImplementableEvent, Category = "Item|Event")
    void OnItemPickedUp();

정리

리플렉션 시스템 주요 기능

  • BP 통합 :
    C++에서 정의한 클래스와 함수를 BP에서 사용할 수 있음.
  • 런타임 조작 :
    리플렉션을 통해 런타임에 객체의 속성 값을 수정하거나 함수를 동적으로 호출할 수 있음.
  • 에디터 지원 :
    리플렉션 시스템을 사용하면 에디터에서 객체의 속성을 수정하고 게임 로직을 테스트할 수 있음.

장단점

  • 장점
    • BP와 C++의 통합이 용이
    • 런타임 조작이 가능 => 게임의 유연성을 높임
    • 에디터 지원을 통해 개발 속도가 빨라짐
  • 단점
    • 코드가 복잡해질 수 있으며, 성능에 약간의 영향을 줄 수 있음.
    • 메타데이터를 잘못 설정하면 디버깅이 어려워질 수 있음.
profile
만성피로 개발자

0개의 댓글