개인 강의/Unreal Engine 멀티플레이어 게임 개발

Unreal Engine 멀티플레이어 게임 개발 2-2

jh009 2026. 7. 29. 19:17

2-2. 멀티플레이 채팅 구현

내가 작성한 채팅 메시지가 다른 PC 화면에 나오게 하려면?

내가 작성한 채팅 메시지는 일단 서버로 전송해야 함.

서버는 전송 받은 메세지를 다시 클라이언트들에게 전송해줘야 함.


멀티플레이 채팅 구현

// CXPlayerController.h

...
class CHATX_API ACXPlayerController : public APlayerController
{
	...

public:
	...

	UFUNCTION(Client, Reliable)
	void ClientRPCPrintChatMessageString(const FString& InChatMessageString);

	UFUNCTION(Server, Reliable)
	void ServerRPCPrintChatMessageString(const FString& InChatMessageString);
	
protected:
	...
	
};

 

Implementation > RPC를 만들 때의 문법

// CXPlayerController.cpp


...
#include "EngineUtils.h"

...

void ACXPlayerController::SetChatMessageString(const FString& InChatMessageString)
{
	ChatMessageString = InChatMessageString;

	//PrintChatMessageString(InChatMessageString);
	if (IsLocalController() == true)
	{
		ServerRPCPrintChatMessageString(InChatMessageString);		
	}
}

...

void ACXPlayerController::ClientRPCPrintChatMessageString_Implementation(const FString& InChatMessageString)
{
	PrintChatMessageString(InChatMessageString);
}

void ACXPlayerController::ServerRPCPrintChatMessageString_Implementation(const FString& InChatMessageString)
{
	for (TActorIterator<ACXPlayerController> It(GetWorld()); It; ++It)
	{
		ACXPlayerController* CXPlayerController = *It;
		if (IsValid(CXPlayerController) == true)
		{
			CXPlayerController->ClientRPCPrintChatMessageString(InChatMessageString);
		}
	}
}

Client RPC 대신에 NetMulticast RPC를 사용을 한다면?

내 PC와 서버 PC에만 채팅이 보이게 됨.


누군가가 접속하면 메세지를 띄우기

플레이어가 접속할 때마다 호출되는 함수

  • 로그인 관현 함수

Server RPC, Client RPC, Multicast RPC 중 무엇을 사용해야 할까요?

 

Multicast RPC를 쓴다면, “게임 모드/게임 스테이트” 중 어느 액터에서 정의해야 할까요?

 


NetMulticast RPC를 통한 서버 접속 알리기

 

GameModeBase를 만들었다면 GameState도 GameStateBase로 만들어야함.

반대로,  GameMode를 만들었다면 GameState도 GameState로 만들어야함.

 

New C++ 클래스 > GameStateBase 부모 클래스 > “CXGameStateBase”

Path: Game

 

Content Browser > Content > ChatX > BP > Game New BP 클래스

> CXGameStateBase 부모 클래스 > “BP_GameStateBase”

 

BP_GameModeBase > Details > Game State Class에 BP_GameStateBase 지정.

 

FString(TEXT("XXXXXXX") > 임시로 XXXXXXX 입력.

// CXGameStateBase.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/GameStateBase.h"
#include "CXGameStateBase.generated.h"

/**
 * 
 */
UCLASS()
class CHATX_API ACXGameStateBase : public AGameStateBase
{
	GENERATED_BODY()

public:
	UFUNCTION(NetMulticast, Reliable)
	void MulticastRPCBroadcastLoginMessage(const FString& InNameString = FString(TEXT("XXXXXXX")));
										  
};
// CXGameStateBase.cpp


#include "CXGameStateBase.h"

#include "Kismet/GameplayStatics.h"
#include "Player/CXPlayerController.h"

void ACXGameStateBase::MulticastRPCBroadcastLoginMessage_Implementation(const FString& InNameString)
{
	if (HasAuthority() == false)
	{
		APlayerController* PC = UGameplayStatics::GetPlayerController(GetWorld(), 0);
		if (IsValid(PC) == true)
		{
			ACXPlayerController* CXPC = Cast<ACXPlayerController>(PC);
			if (IsValid(CXPC) == true)
			{
				FString NotificationString = InNameString + TEXT(" has joined the game.");
				CXPC->PrintChatMessageString(NotificationString);
			}
		}
	}
}
// CXGameModeBase.h

...
class CHATX_API ACXGameModeBase : public AGameModeBase
{
	GENERATED_BODY()

public:
	virtual void OnPostLogin(AController* NewPlayer) override;	
	
};
// CXGameModeBase.cpp


#include "Game/CXGameModeBase.h"

#include "CXGameStateBase.h"

void ACXGameModeBase::OnPostLogin(AController* NewPlayer)
{
	Super::OnPostLogin(NewPlayer);

	ACXGameStateBase* CXGameStateBase =  GetGameState<ACXGameStateBase>();
	if (IsValid(CXGameStateBase) == true)
	{
		CXGameStateBase->MulticastRPCBroadcastLoginMessage(TEXT("XXXXXXX"));
	}
}