해당 포스팅은 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 매크로에 프로퍼티 메타데이터와 변수 지정자를 붙여 선언하면 된다.
일반적으로 사용되는 예시는 다음과 같다.
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Stats")
float Health = 100.f;- 에디터에서 수정 가능
- 블루프린트에서 읽기/쓰기 모두 가능
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 예시
UFUNCTION(BlueprintCallable, Category="Player")
void IncreaseHealth(float Amount);void AMyCharacter::IncreaseHealth(float Amount)
{
Health += Amount;
}✔️ 블루프린트에서 하는 일
- 노드로 나타나며 직접 호출 가능
- "Increase Health"로 검색됨
2️⃣ BlueprintImplementableEvent 예시
UFUNCTION(BlueprintImplementableEvent, Category="Effects")
void PlayLevelUpEffect();✔️ 블루프린트에서 하는 일
- "PlayLevelUpEffect"를 이벤트 그래프에서 Override
- 파티클 재생, 사운드 출력 등 원하는 기능 구현
3️⃣ BlueprintNativeEvent 예시
UFUNCTION(BlueprintNativeEvent, Category="Damage")
void ApplyDamage(float Damage);
virtual void ApplyDamage_Implementation(float Damage);void AMyCharacter::ApplyDamage_Implementation(float Damage)
{
Health -= Damage;
UE_LOG(LogTemp, Log, TEXT("C++ 기본 데미지 처리: %f"), Damage);
}✔️ 블루프린트에서 하는 일
- "ApplyDamage"를 override 가능
- 블루프린트에서는 C++ 기본 구현을 대체하거나 호출(super) 가능
더 자세한 내용은 공식 문서의 UFunctions을 참고하면 좋다.