1-1. 채팅 프로젝트 생성
1. 프로젝트 생성
UE5.5.4 기준 프로젝트 세팅
코드 선택 → Ctrl + . 누르기 → Create Declaration / Definition 선택하면 cpp 코드를 자동을 짜줌
2. 새 레벨 만들기
Content Browser > Content 폴더 우클릭 > 새 폴더 “ChatX”
ChatX 폴더 우클릭 > 새 폴더 “Maps”
File > New Level > Empty Level 선택 후 Create
Ctrl + S > Maps 폴더 "Chatting" 이름 설정

3. 레벨 관련 프로젝트 설정
Project Settings > Maps & Modes > Chatting 지정
- Editor Startup Map
- Game Default Map
4. 게임 프레임워크 블루프린트 에셋 생성
New C++ 클래스 > GameModeBase 부모 클래스 > “CXGameModeBase”`
Path: Game (경로 뒤에 Game 추가)
New C++ 클래스 > PlayerController 부모 클래스 > “CXPlayerController”`
Path: Player (경로 뒤에 Player 추가)
// CXGameModeBase.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "CXGameModeBase.generated.h"
UCLASS()
class CHATX_API ACXGameModeBase : public AGameModeBase
{
GENERATED_BODY()
};
// CXGameModeBase.cpp
#include "Game/CXGameModeBase.h"
// CXPlayerController.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "CXPlayerController.generated.h"
UCLASS()
class CHATX_API ACXPlayerController : public APlayerController
{
GENERATED_BODY()
};
// CXPlayerController.cpp
#include "Player/CXPlayerController.h"
// ChatX.Build.cs
using UnrealBuildTool;
public class ChatX : ModuleRules
{
public ChatX(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[]
{
// Initial Dependencies
"Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput",
});
PrivateDependencyModuleNames.AddRange(new string[] { });
PublicIncludePaths.AddRange(new string[] { "ChatX" }); // 추가
}
}
- Content Browser > Content 폴더 > ChatX 폴더 우클릭 > 새 폴더 “Blueprint”`
- Blueprint > 새 폴더 “Game”, “Player”`
- Game > 새 Blueprint 에셋 > CXGameModeBase 부모 클래스 > “BP_GameModeBase”`
- Player > 새 Blueprint 에셋 > CXPlayerController 부모 클래스 > “BP_PlayerController”
Chatting 레벨 > World Settings > GameMode Override에 BP_GameMode 지정

BP_GameModeBase > Details > Player Controller Class에 BP_PlayerController 지정

5. 채팅 입력창 위젯 구현
New C++ 클래스 > UserWidget 부모 클래스 > “CXChatInput”
Path: UI
// ChatX.Build.cs
...
public class ChatX : ModuleRules
{
public ChatX(ReadOnlyTargetRules Target) : base(Target)
{
...
PublicDependencyModuleNames.AddRange(new string[]
{
...
// UI
"UMG",
});
...
}
}
// CXChatInput.h
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "CXChatInput.generated.h"
class UEditableTextBox;
/**
*
*/
UCLASS()
class CHATX_API UCXChatInput : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(meta = (BindWidget))
TObjectPtr<UEditableTextBox> EditableTextBox_ChatInput;
};
// CXChatInput.cpp
#include "UI/CXChatInput.h"
- Content Browser > Content 폴더 > Chat 폴더 > Blueprint 우클릭 > 새 폴더 “UI”
- UI > 새 User Interface 에셋 > Widget Blueprint
- CXChatInput 부모 클래스 > “WBP_ChatInput”
WBP_ChatInput > Hierarchy에 Cavas Panel 추가

WBP_ChatInput > Hierarchy에 EditableTextBox 추가

Text Box > Details > Anchors에서 하단을 꽉채우는 걸로 선택
Text Box > Details


6. 채팅 위젯 연결
코드 작성 후, BP_PlayerController > Chat Input Widget Class에 WBP_ChatInput 지정
// CXPlayerController.h
...
class UCXChatInput;
/**
*
*/
UCLASS()
class CHATX_API ACXPlayerController : public APlayerController
{
GENERATED_BODY()
public:
virtual void BeginPlay() override;
protected:
UPROPERTY(EditDefaultsOnly)
TSubclassOf<UCXChatInput> ChatInputWidgetClass;
UPROPERTY()
TObjectPtr<UCXChatInput> ChatInputWidgetInstance;
};
// CXPlayerController.cpp
#include "Player/CXPlayerController.h"
#include "UI/CXChatInput.h"
void ACXPlayerController::BeginPlay()
{
Super::BeginPlay();
FInputModeUIOnly InputModeUIOnly;
SetInputMode(InputModeUIOnly);
if (IsValid(ChatInputWidgetClass) == true)
{
ChatInputWidgetInstance = CreateWidget<UCXChatInput>(this, ChatInputWidgetClass);
if (IsValid(ChatInputWidgetInstance) == true)
{
ChatInputWidgetInstance->AddToViewport();
}
}
}
BP_PlayerController > Details > Chat Input Widget Class에 WBP_ChatInput

7. 채팅 메세지 관리
// ChatX.Build.cs
...
public class ChatX : ModuleRules
{
public ChatX(ReadOnlyTargetRules Target) : base(Target)
{
...
PublicDependencyModuleNames.AddRange(new string[]
{
...
// UI
"UMG", "Slate", "SlateCore",
});
...
}
}
// CXPlayerController.h
...
class CHATX_API ACXPlayerController : public APlayerController
{
...
public:
virtual void BeginPlay() override;
void SetChatMessageString(const FString& InChatMessageString);
protected:
...
FString ChatMessageString;
};
// CXPlayerController.cpp
...
void ACXPlayerController::SetChatMessageString(const FString& InChatMessageString)
{
ChatMessageString = InChatMessageString;
}
// CXChatInput.h
...
#include "Types/SlateEnums.h"
#include "CXChatInput.generated.h"
...
class CHATX_API UCXChatInput : public UUserWidget
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
virtual void NativeDestruct() override;
protected:
UFUNCTION()
void OnChatInputTextCommitted(const FText& Text, ETextCommit::Type CommitMethod);
public:
...
};
// CXChatInput.cpp
#include "UI/CXChatInput.h"
#include "Components/EditableTextBox.h"
#include "Player/CXPlayerController.h"
void UCXChatInput::NativeConstruct()
{
Super::NativeConstruct();
if (EditableTextBox_ChatInput->OnTextCommitted.IsAlreadyBound(this, &ThisClass::OnChatInputTextCommitted) == false)
{
EditableTextBox_ChatInput->OnTextCommitted.AddDynamic(this, &ThisClass::OnChatInputTextCommitted);
}
}
void UCXChatInput::NativeDestruct()
{
Super::NativeDestruct();
if (EditableTextBox_ChatInput->OnTextCommitted.IsAlreadyBound(this, &ThisClass::OnChatInputTextCommitted) == true)
{
EditableTextBox_ChatInput->OnTextCommitted.RemoveDynamic(this, &ThisClass::OnChatInputTextCommitted);
}
}
void UCXChatInput::OnChatInputTextCommitted(const FText& Text, ETextCommit::Type CommitMethod)
{
if (CommitMethod == ETextCommit::OnEnter)
{
APlayerController* OwningPlayerController = GetOwningPlayer();
if (IsValid(OwningPlayerController) == true)
{
ACXPlayerController* OwningCXPlayerController = Cast<ACXPlayerController>(OwningPlayerController);
if (IsValid(OwningCXPlayerController) == true)
{
OwningCXPlayerController->SetChatMessageString(Text.ToString());
EditableTextBox_ChatInput->SetText(FText());
}
}
}
}
8. 채팅 메세지 출력
// CXPlayerController.h
...
class CHATX_API ACXPlayerController : public APlayerController
{
GENERATED_BODY()
public:
...
void PrintChatMessageString(const FString& InChatMessageString);
protected:
...
};
// CXPlayerController.cpp
..
#include "Kismet/KismetSystemLibrary.h"
...
void ACXPlayerController::SetChatMessageString(const FString& InChatMessageString)
{
...
PrintChatMessageString(ChatMessageString);
}
void ACXPlayerController::PrintChatMessageString(const FString& InChatMessageString)
{
UKismetSystemLibrary::PrintString(this, ChatMessageString, true, true, FLinearColor::Red, 5.0f);
}'개인 강의 > Unreal Engine 멀티플레이어 게임 개발' 카테고리의 다른 글
| Unreal Engine 멀티플레이어 게임 개발 2-1 (0) | 2026.07.29 |
|---|---|
| Unreal Engine 멀티플레이어 게임 개발 1-5 (0) | 2026.07.29 |
| Unreal Engine 멀티플레이어 게임 개발 1-4 (0) | 2026.07.29 |
| Unreal Engine 멀티플레이어 게임 개발 1-3 (0) | 2026.07.28 |
| Unreal Engine 멀티플레이어 게임 개발 1-2 (0) | 2026.07.28 |