Blog

ENGINEERING NOTE

[Unreal Engine] 언리얼 엔진5와 레이어 이해하기

해당 포스팅은 Stuart Butler , Tom Oliver의 Game Development Patterns with Unreal Engine 5를 바탕으로 작성한 내용입니다.대부분의 엔진은 레이어라는 개념으로 작동한다. 각 레이어마다 특정한 작업이 배정되어 있으며,

Unreal Engine
해당 포스팅은 Stuart Butler , Tom Oliver의 Game Development Patterns with Unreal Engine 5를 바탕으로 작성한 내용입니다.

Layer In Unreal Engine

대부분의 엔진은 레이어라는 개념으로 작동한다. 각 레이어마다 특정한 작업이 배정되어 있으며, 이를 올바른 순서로 쌓으면 엔진의 개발과 유지 관리가 간소화된다.

언리얼엔진에서도 C++과 블루프린트 게임플레이를 처리하는 방식에서 실제로 이런 레이어가 동작함을 확인할 수 있다.

예를 들어,

  • C++에서 특정한 지정자로 생성한 함수는 블루프린트에서 액세스할 수 있지만, 그 역은 성립하지 않는다.

이러한 동작은 레이어 간 순서가 존재하고 서로 분리된 레이어에서 작업한다는 점을 의미한다.

언리얼엔진의 구조와 레이어에 대한 더 자세한 사항은 공식 문서의 엔진 시작하기 | 엔진 구조를 참고하면 좋다.

언리얼엔진은 기본적으로 C++을 사용하지만 복잡한 코드를 더 쉽게 사용할 수 있도록 블루프린트 스크립팅을 지원한다.

덕분에 엔진을 사용하는 사람들은 블루프린트를 통해 에디터 내부에서 시스템을 더욱 간단하고 쉽게 접근할 수 있다. 이러한 시스템을 리플렉션 시스템(Reflection System)이라고도 부른다.

또한 이런 레이어와 시스템의 구성을 쉽게 개발하기 위해 언리얼엔진에서는 엔진에서 에디터로 신호 전달 벙식을 정의할 수 있는 프로퍼티 지정자(Property Specifier)를 제공한다.


프로퍼티 지정자(Property Specifier)

프로퍼티 지정자는 C++에서 정의한 변수를 블루프린트 레이어에서 보거나 액세스할 때의 특성을 정의한다.

사용법은 UPROPERTY 매크로에 프로퍼티 메타데이터와 변수 지정자를 붙여 선언하면 된다.

일반적으로 사용되는 예시는 다음과 같다.


cpp
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stats")
float Health = 100.f;
  • 에디터에서 수정 가능
  • 블루프린트에서 읽기/쓰기 모두 가능

cpp
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Components")
UStaticMeshComponent* Mesh;
  • 에디터에서 보기만 가능(수정 불가)
  • 블루프린트에서는 읽기만 가능

더 자세한 내용은 공식 문서의 프로퍼티를 참고하면 좋다.

함수 지정자(Function Specifiers)

함수 지정자 역시 프로퍼티 지정자와 비슷하게 사용할 수 있다.

모든 UObject 또는 블루프린트 함수 라이브러리는 UFUNCTION 매크로를 헤더 파일 내 함수 선언 윗줄에 배치하여 멤버 함수를 UFunction으로 선언할 수 있다.

일반적으로 이용되는 3가지에 대해서 간단히 표와 예시로 알아보자.

지정자C++ 구현 필요?블루프린트에서 구현 가능?블루프린트에서 호출 가능?용도
BlueprintCallable선택(있어도 되고 없음도 가능)❌ 구현 불가✔️ 호출 가능BP에서 C++ 함수를 호출하고 싶을 때
BlueprintImplementableEvent❌ C++ 구현 불가✔️ 반드시 BP에서 구현✔️ 호출 가능"이벤트를 BP에서만 구현"하고 싶을 때
BlueprintNativeEvent✔️ C++ 기본 구현 필요(또는 optional)✔️ BP에서 override 가능✔️ 호출 가능"C++에도 기본 구현을 두고, BP에서도 override 가능한" 함수

1️⃣ BlueprintCallable 예시

cpp
UFUNCTION(BlueprintCallable, Category="Player")
void IncreaseHealth(float Amount);
cpp
void AMyCharacter::IncreaseHealth(float Amount)
{
    Health += Amount;
}

✔️ 블루프린트에서 하는 일

  • 노드로 나타나며 직접 호출 가능
  • "Increase Health"로 검색됨

2️⃣ BlueprintImplementableEvent 예시

cpp
UFUNCTION(BlueprintImplementableEvent, Category="Effects")
void PlayLevelUpEffect();

✔️ 블루프린트에서 하는 일

  • "PlayLevelUpEffect"를 이벤트 그래프에서 Override
  • 파티클 재생, 사운드 출력 등 원하는 기능 구현

3️⃣ BlueprintNativeEvent 예시

cpp
UFUNCTION(BlueprintNativeEvent, Category="Damage")
void ApplyDamage(float Damage);
virtual void ApplyDamage_Implementation(float Damage);
cpp
void AMyCharacter::ApplyDamage_Implementation(float Damage)
{
    Health -= Damage;
    UE_LOG(LogTemp, Log, TEXT("C++ 기본 데미지 처리: %f"), Damage);
}

✔️ 블루프린트에서 하는 일

  • "ApplyDamage"를 override 가능
  • 블루프린트에서는 C++ 기본 구현을 대체하거나 호출(super) 가능

더 자세한 내용은 공식 문서의 UFunctions을 참고하면 좋다.