어떤 이벤트가 발생했을 때에 콜백 함수를 호출할 수 있게 하는 것을 델리게이트라고 한다. 이 델리게이트를 이용해서 콜백 함수들을 실행하며 멀티플레이어 세션 환경을 구축하였다.
세션 인터페이스에는 여러 델리게이트가 기 생성되어 있고, 요구하는 파라미터 타입을 맞춘 콜백 함수를 바인딩하여 사용할 수 있었다.
이러한 델리게이트들을 직접 만들어 사용할 수 있는데 이를 Custom Delegate라고 한다.
델리게이트의 타입에는 여러 개가 있으며 DelegateCombinations.h
에서 찾아볼 수 있다.
DECLARE_DYNAMIC_MULTICAST_DELEGATE
, DECLARE_MULTICAST_DELEGATE
을 사용할 것이다.
DECLARE_DYNAMIC_MULTICAST_DELEGATE
의 형식으로 델리게이트를 선언하게 되면, 이 델리게이트는 런타임에 바인딩과 언바인딩이 가능하다. 또한 블루프린트와 호환이 가능하기 때문에 블루프린트에서 이 델리게이트를 사용할 수 있다.
DECLARE_MULTICAST_DELEGATE
의 형식으로 델리게이트를 선언하면 이 델리게이트는 정적이며, 블루프린트에서 접근할 수 없고 C++에서만 사용할 수 있다. 또한 런타임에서 바인딩/언바인딩이 불가능하다.
DECLARE_DYNAMIC_MULTICAST_DELEGATE
는 블루프린트에서 사용할 수 있으므로 UI 이벤트나 다른 블루프린트와의 상호작용 등에서 유용하다.
델리게이트의 파라미터로 사용하는 타입이 블루프린트에서 지원하지 않는 경우에는 다이나믹 멀티캐스트를 사용할 수 없다. 예컨대 FOnlineSessionSearchResult
와 같이 블루프린트에서 인식할 수 없는 자료형을 파라미터로 사용하는 콜백 함수를 바인딩할 델리게이트를 선언하기 위해서는 정적 델리게이트로 선언해야 한다.
또한 바인딩할 함수가 정적 함수인 경우에도 다이나믹 델리게이트를 사용할 수 없다. 다이나믹 델리게이트는 인스턴스가 필요하다.
FMultiplayerOnCreateSessionComplete MultiplayerOnCreateSessionComplete;
FMultiplayerOnFindSessionsComplete MultiplayerOnFindSessionsComplete;
FMultiplayerOnJoinSessionComplete MultiplayerOnJoinSessionComplete;
FMultiplayerOnDestroySessionComplete MultiplayerOnDestroySessionComplete;
FMultiplayerOnStartSessionComplete MultiplayerOnStartSessionComplete;
세션 환경 구축에 필요한 5가지 델리게이트 클래스 타입을 생성했다.
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnCreateSessionComplete, bool, bWasSuccessful);
DECLARE_MULTICAST_DELEGATE_TwoParams(FMultiplayerOnFindSessionsComplete, const TArray<FOnlineSessionSearchResult>& SessionResults, bool bWasSuccessful);
DECLARE_MULTICAST_DELEGATE_OneParam(FMultiplayerOnJoinSessionComplete, EOnJoinSessionCompleteResult::Type Result);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnDestroySessionComplete, bool, bWasSuccessful);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnStartSessionComplete, bool, bWasSuccessful);
헤더 파일에서 델리게이트를 선언한다. FOnlineSessionSearchResult
, EOnJoinSessionCompleteResult
타입의 콜백 함수가 바인딩될 FindSessionsComplete
, 그리고 JoinSessionComplete
함수는 DECLARE_MULTICAST_DELEGATE
로 선언하고 있음에 유의.
UFUNCTION()
void OnCreateSession(bool bWasSuccessful);
void OnFindSessions(const TArray<FOnlineSessionSearchResult>& SessionResults, bool bWasSuccessful);
void OnJoinSession(EOnJoinSessionCompleteResult::Type Result);
UFUNCTION()
void OnDestroySession(bool bWasSuccessful);
UFUNCTION()
void OnStartSession(bool bWasSuccessful);
콜백 함수가 호출될 클래스의 헤더 파일에서 콜백 함수를 선언한다. 다이나믹 델리게이트로 바인딩될 콜백 함수에는 반드시 UFUNCTION()
매크로가 붙어야 한다.
UGameInstance* GameInstance = GetGameInstance();
if (GameInstance)
{
MultiplayerSessionsSubsystem = GameInstance->GetSubsystem<UMultiplayerSessionsSubsystem>();
}
if (MultiplayerSessionsSubsystem)
{
MultiplayerSessionsSubsystem->MultiplayerOnCreateSessionComplete.AddDynamic(this, &ThisClass::OnCreateSession);
MultiplayerSessionsSubsystem->MultiplayerOnFindSessionsComplete.AddUObject(this, &ThisClass::OnFindSessions);
MultiplayerSessionsSubsystem->MultiplayerOnJoinSessionComplete.AddUObject(this, &ThisClass::OnJoinSession);
MultiplayerSessionsSubsystem->MultiplayerOnDestroySessionComplete.AddDynamic(this, &ThisClass::OnDestroySession);
MultiplayerSessionsSubsystem->MultiplayerOnStartSessionComplete.AddDynamic(this, &ThisClass::OnStartSession);
}
GameInstance->GetSubsystem<>()
으로 델리게이트가 선언된 서브시스템에 접근하고, 콜백 함수를 바인딩한다.
이 때에도 마찬가지로 동적 델리게이트는 AddDynamic
으로, 정적 델리게이트는 AddUObject
로 바인딩하고 있음에 유의.
이 델리게이트를 발생시키는 방법은 BroadCast()
함수를 이용하면 된다. 이 함수 내부에 콜백 함수에 맞는 인풋 파라미터를 함께 전달하면, 해당 델리게이트에 바인딩 되어 있는 모든 콜백 함수들이 실행된다.
// 선언
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnCreateSessionComplete, bool, bWasSuccessful);
...
// 호출
MultiplayerOnCreateSessionComplete.Broadcast(false);