SKYLIGHT STUDIO

[Unreal C++] UFUNCTION 본문

Game Development/Unity C#

[Unreal C++] UFUNCTION

SKY_L 2024. 1. 17. 07:52
	UFUNCTION(BlueprintPure, Category ="Power")
	EBatteryPlayState GetCurrentState() const;

 

언리얼 C++을 학습하기 시작하면 가장 먼저 골치아픈 부분이다.

UFUNCTION... UENUM... UPROPERTY...

 

일종의 UClass 멤버나 함수를 정의하거나 선언할 때 사용하는 매크로라고 생각하면 된다.

좀 더 구체적으로 설명해보자면...

 

 

언리얼에서는 함수가 C++UFUNCTION 두 가지 형태로 존재할 수 있다. 일단 둘다 .h 클래스 헤더 파일에 선언된다. 둘의 차이점은 크진 않지만 함수 지정자(하단에서 설명)을 통해 선언에 함수 관련 추가 정보를 지정해주어야 한다.

 

UFUNCTION은 C++의 강화판이라고 봐도 무방하다. C++ 구현이 있고, C++ 코드 내에서 호출할 수도 있고, 함수 본문 내에서 다른 C++ 함수 또는 UFUNCTION에 대한 호출을 포함할 수 있다. 사실 이것만 봐도 C++과 다른 점도 없다.

 

그렇지만 조금 다른 점도 있다!

 

 

언리얼의 가장 강력한 기능 중 하나인 블루프린트 비주얼 스크립팅 시스템 안에서 호출 또는 오버라이드 가능하다는 것. BlueprintCallable, BlueprintPure, BlueprintImplementableEvent 지정자로 선언된 UFUNCTION은 블루프린트에 노출될 수 있다.

 

예를 들면 이렇게...

 


 

함수 지정자

UFUNCTION의 기본 형태는 다음과 같다.

 

UFUNCTION([specifier, specifier, ...], [meta(key=value, key=value, ...)])
ReturnType FunctionName([Parameter, Parameter, ...])

 

여기서 specifier, 즉 함수 지정자가 중요한 역할을 수행한다. 이들은 영문(specifier) 그대로 함수의 특성화를 수행할 수 있다. 여기서는 중요한 함수 지정자들을 꼽아 설명한다.

 

● BlueprintCallable

 

예제

UFUNCTION(BlueprintCallable, Category = "MyCategory")
void MyFunction();

 

가장 일반적으로 사용되는 함수 지정자. 말 그대로 해당 함수가 블루프린트에서 호출 가능해져, 노드로 사용할 수 있게 되는 것. BlueprintPure과의 차이점은 하기에서 설명한다.

 

● BlueprintPure

 

예제

UFUNCTION(BlueprintPure, Category = "MyCategory")
int32 GetMyValue() const;

 

일반적으로 BlueprintCallable과 비슷하다. 비슷하긴 한데... 'Pure'이라는 키워드처럼 순수 함수의 형태로 반환하게 된다.

이해를 위해서는 순수함수에 대한 이해가 선행되어야 한다.

 

순수 함수는 함수형 프로그래밍의 개념 중 하나로, 오로지 입력(인풋)값에만 의존하고 외부 상태에 영향을 받지 않는 함수를 가리킨다. 즉 같은 입력이 들어오면 어떠한 상황에도 항상 동일한 출력만을 반환해야 한다는 것. 단순히 말하면 고인 물에서 노는 애들은 순수 함수다.

 

결과론적으로 블루프린트에서 이 함수를 호출할 때, 해당 함수의 반환값만을 사용할 수 있다.

 

대표적인 사용례.

 

반례.

 

● BlueprintImplementableEvent

 

예제

UFUNCTION(BlueprintImplementableEvent, Category = "MyCategory")
void OnEventTriggered();

 

해당 함수를 C++에서 구현하지 않고, 해당 함수를 블루프린트에서 구현할 수 있게 해주는 지정자다. 왜 이렇게까지 하냐 싶겠지만, 언리얼 C++ 컴파일러는 함수가 정의되어있지 않으면 컴파일 에러가 발생하는 관계로...

 

어쨌건 이런 함수들은 C++에서 비어있는 상태로 남겨두고, 함수의 원하는 동작을 블루프린트에서 구현하면 된다.

 

● BlueprintICosmetic

 

예제

UFUNCTION(BlueprintCosmetic, Category = "Visuals")
void SetVisualEffect();

 

주로 시각적인 측면에서만 사용되고, 게임 로직에 큰 영향을 미치지 않는다는 것을 나타낼 때. 블루프린트의 시각적인 표현을 위한 함수에 사용된다. 장식에 가까운 함수라 데디케이티드 서버에서는 실행되지 않는다. 난 써본 적이 없는 것 같음.

 

 

● BlueprintGetter

 

예제

UPROPERTY(BlueprintGetter=GetMyProperty, Category = "MyCategory")
int32 MyProperty;

UFUNCTION(BlueprintPure, Category = "MyCategory")
int32 GetMyProperty() const;

 

블루프린트에서 해당 속성에 대한 Getter 함수를 생성시키는 함수. 그러니까 해당 속성의 값을 블루프린트로 가져올 때 사용하는 함수이다.

 

● BlueprintAuthorityOnly

 

예제

UFUNCTION(BlueprintAuthorityOnly, Category = "MyCategory")
void ServerOnlyFunction();

 

해당 함수가 서버에서만 실행되어야 함을 나타낸다. 권한 문제를 나타낸다는 것. 따라서 클라이언트에서 호출되면 이 함수는 자연히 무시된다.

 

● BlueprintNativeEvent

 

예제

	UFUNCTION(BlueprintNativeEvent)
	void WasCollected();
	virtual void WasCollected_Implementation();
void APickup::WasCollected_Implementation() {
	// 디버그 메시지 출력
	FString PickupDebugString = GetName();
	UE_LOG(LogClass, Log, TEXT("You have collected %s"), *PickupDebugString);
}

 

이건 꽤 중요한 함수다. 블루프린트에서 구현한 네이티브 이벤트를 나타낸다는 것. 구체적으로 설명해자면, C++에서 네이티브 이벤트의 기본 동작을 제공하고, 블루프린트에서는 이 이벤트를 오버라이드하여 사용할 수 있다


 

여기서부터는 함수 자체보다는 함수 자체의 기능성에 주안을 둔 지정자들이다.

 

서버/클라이언트

네트워크 기능과 관련된 지정자들. 보통 멀티플레이어 게임에서 서버 및 클라이언트 간의 함수 호출을 지정한다.

 

● Server

 

예제

UFUNCTION(Server, Reliable, WithValidation)
void ServerFunction();

 

● Client

 

예제

UFUNCTION(Client, Reliable)
void ClientFunction();

 

쓰던 것이 날아가서 짜증나는 관계로... 70% 가량만 완성하고 업로드.

다음에 복기할 때 남은 것을 작성하자!