콘텐츠로 이동

UE5 Gameplay Message Router — 이벤트 브로드캐스트

Gameplay Message Router(UGameplayMessageSubsystem)는 UE5의 GameFeatures 플러그인에 포함된 타입 안전 메시지 브로드캐스트 시스템입니다. 발신자와 수신자가 서로를 알 필요 없이 GameplayTag 채널로 메시지를 주고받아 컴포넌트 간 결합을 줄입니다.


Edit > Plugins > GameFeatures → 활성화
Edit > Plugins > ModularGameplay → 활성화
.uproject 또는 .Build.cs:
Build.cs
PublicDependencyModuleNames.AddRange(new[]
{
"GameplayMessageRuntime", // 핵심 모듈
"GameplayTags",
});

Game.Message.Player.Died
// 채널 태그 정의 (GameplayTags.ini 또는 코드)
// Game.Message.Item.Picked
USTRUCT(BlueprintType)
struct FPlayerDiedMessage
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite)
APlayerState* PlayerState = nullptr;
UPROPERTY(BlueprintReadWrite)
FVector DeathLocation;
UPROPERTY(BlueprintReadWrite)
AActor* Killer = nullptr;
UPROPERTY(BlueprintReadWrite)
int32 RemainingLives = 0;
};
USTRUCT(BlueprintType)
struct FItemPickedMessage
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite)
FGameplayTag ItemTag;
UPROPERTY(BlueprintReadWrite)
int32 Quantity = 1;
UPROPERTY(BlueprintReadWrite)
AActor* Picker = nullptr;
};

#include "GameFramework/GameplayMessageSubsystem.h"
// 플레이어 사망 메시지 발송
void AMyCharacter::Die(AActor* Killer)
{
// ... 사망 처리 로직 ...
// 메시지 브로드캐스트
UGameplayMessageSubsystem& MsgSys =
UGameplayMessageSubsystem::Get(GetWorld());
FPlayerDiedMessage Msg;
Msg.PlayerState = GetPlayerState();
Msg.DeathLocation = GetActorLocation();
Msg.Killer = Killer;
Msg.RemainingLives = LivesComponent->GetLives();
MsgSys.BroadcastMessage(
TAG_GameMessage_Player_Died, // FGameplayTag
Msg);
}
// 아이템 획득 메시지
void APickup::OnPickedUp(AActor* Picker)
{
UGameplayMessageSubsystem& MsgSys =
UGameplayMessageSubsystem::Get(GetWorld());
FItemPickedMessage Msg;
Msg.ItemTag = ItemTag;
Msg.Quantity = StackSize;
Msg.Picker = Picker;
MsgSys.BroadcastMessage(TAG_GameMessage_Item_Picked, Msg);
Destroy();
}

#include "GameFramework/GameplayMessageSubsystem.h"
UCLASS()
class AGameHUD : public AHUD
{
GENERATED_BODY()
private:
FGameplayMessageListenerHandle _deathHandle;
FGameplayMessageListenerHandle _itemHandle;
public:
virtual void BeginPlay() override
{
Super::BeginPlay();
RegisterListeners();
}
virtual void EndPlay(const EEndPlayReason::Type Reason) override
{
// 반드시 해제 (메모리 누수 방지)
UGameplayMessageSubsystem& MsgSys =
UGameplayMessageSubsystem::Get(GetWorld());
MsgSys.UnregisterListener(_deathHandle);
MsgSys.UnregisterListener(_itemHandle);
Super::EndPlay(Reason);
}
private:
void RegisterListeners()
{
UGameplayMessageSubsystem& MsgSys =
UGameplayMessageSubsystem::Get(GetWorld());
// 플레이어 사망 수신
_deathHandle = MsgSys.RegisterListener<FPlayerDiedMessage>(
TAG_GameMessage_Player_Died,
this,
&AGameHUD::OnPlayerDied);
// 아이템 획득 수신
_itemHandle = MsgSys.RegisterListener<FItemPickedMessage>(
TAG_GameMessage_Item_Picked,
this,
&AGameHUD::OnItemPicked);
}
void OnPlayerDied(FGameplayTag Channel,
const FPlayerDiedMessage& Msg)
{
// HUD에 사망 알림 표시
ShowDeathNotification(Msg.PlayerState, Msg.Killer);
UpdateLivesDisplay(Msg.RemainingLives);
}
void OnItemPicked(FGameplayTag Channel,
const FItemPickedMessage& Msg)
{
ShowItemPickupFeedback(Msg.ItemTag, Msg.Quantity);
}
};

BP에서 발신:
- GameplayMessageSubsystem > Broadcast Message 노드
- 채널: GameplayTag 선택
- 메시지: 구조체 핀
BP에서 수신:
- GameplayMessageSubsystem > Register Listener 노드
- On Message 이벤트 핀 연결
- Unregister Listener를 EndPlay에서 호출

6. 메시지 필터링 — 채널 매칭 모드

섹션 제목: “6. 메시지 필터링 — 채널 매칭 모드”
// 정확한 태그 매칭 (기본)
MsgSys.RegisterListener<FMsg>(
TAG_Game_Message_Player_Died,
this, &AClass::Handler,
EGameplayMessageMatch::ExactMatch);
// 부분 매칭: TAG_Game_Message_Player 채널로
// TAG_Game_Message_Player_Died 도 수신
MsgSys.RegisterListener<FMsg>(
TAG_Game_Message_Player,
this, &AClass::Handler,
EGameplayMessageMatch::PartialMatch);
// 예: 모든 Game.Message 수신
MsgSys.RegisterListener<FGenericMessage>(
TAG_Game_Message,
this, &AClass::OnAnyMessage,
EGameplayMessageMatch::PartialMatch);

항목Delegate/EventGameplay Message Router
결합도직접 참조 필요태그만 알면 됨
타입 안전강력구조체 기반
성능빠름약간 오버헤드
사용 범위1:1, 1:NN:N 브로드캐스트
BP 지원제한적완전 지원

Gameplay Message Router는 UI ↔ 게임플레이, 시스템 ↔ 시스템 간 통신에 이상적입니다. FGameplayMessageListenerHandle을 반드시 EndPlay에서 해제하고, 채널 태그는 Game.Message.Domain.Event 형식의 계층 구조로 설계하세요. 성능이 중요한 매 틱 데이터 동기화는 델리게이트를 사용하고, 드물게 발생하는 게임 이벤트 알림에 Message Router를 활용하세요.