UE5 Gameplay Message Router — 이벤트 브로드캐스트
Gameplay Message Router(UGameplayMessageSubsystem)는 UE5의 GameFeatures 플러그인에 포함된 타입 안전 메시지 브로드캐스트 시스템입니다. 발신자와 수신자가 서로를 알 필요 없이 GameplayTag 채널로 메시지를 주고받아 컴포넌트 간 결합을 줄입니다.
1. 플러그인 활성화
섹션 제목: “1. 플러그인 활성화”Edit > Plugins > GameFeatures → 활성화Edit > Plugins > ModularGameplay → 활성화
.uproject 또는 .Build.cs:PublicDependencyModuleNames.AddRange(new[]{ "GameplayMessageRuntime", // 핵심 모듈 "GameplayTags",});2. 메시지 구조체 정의
섹션 제목: “2. 메시지 구조체 정의”// 채널 태그 정의 (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;};3. 메시지 발신
섹션 제목: “3. 메시지 발신”#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();}4. 메시지 수신 — C++
섹션 제목: “4. 메시지 수신 — C++”#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); }};5. Blueprint 연동
섹션 제목: “5. Blueprint 연동”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);7. 기존 델리게이트와 비교
섹션 제목: “7. 기존 델리게이트와 비교”| 항목 | Delegate/Event | Gameplay Message Router |
|---|---|---|
| 결합도 | 직접 참조 필요 | 태그만 알면 됨 |
| 타입 안전 | 강력 | 구조체 기반 |
| 성능 | 빠름 | 약간 오버헤드 |
| 사용 범위 | 1:1, 1:N | N:N 브로드캐스트 |
| BP 지원 | 제한적 | 완전 지원 |
Gameplay Message Router는 UI ↔ 게임플레이, 시스템 ↔ 시스템 간 통신에 이상적입니다. FGameplayMessageListenerHandle을 반드시 EndPlay에서 해제하고, 채널 태그는 Game.Message.Domain.Event 형식의 계층 구조로 설계하세요. 성능이 중요한 매 틱 데이터 동기화는 델리게이트를 사용하고, 드물게 발생하는 게임 이벤트 알림에 Message Router를 활용하세요.