[UE] Multiplayer 7-1: Session 만들기
목차
Session 만들기
IMPLEMENT CreateSession() - MultiplayerSessionsSubsystem
MultiplayerSessionsSubsystem.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "MultiplayerSessionsSubsystem.generated.h"
UCLASS()
class MULTIPLAYERSESSIONS_API UMultiplayerSessionsSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
UMultiplayerSessionsSubsystem();
//
// To handle session functionality. The Menu class will call these
//
void CreateSession(int32 NumPublicConnections, FString MatchType);
void FindSessions(int32 MaxSearchResults);
void JoinSession(const FOnlineSessionSearchResult& SessionResult);
void DestroySession();
void StartSession();
protected:
// Internal callbacks for the delegates we'll add to the Online Session Interface delegate list.
// 아래의 함수들은 이 클래스 밖에서 콜하지 않는다.
void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);
void OnFindSessionsComplete(bool bWasSuccessful);
void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);
void OnDestroySessionComplete(FName SessionName, bool bWasSuccessful);
void OnStartSessionComplete(FName SessionName, bool bWasSuccessful);
private:
IOnlineSessionPtr SessionInterface;
TSharedPtr<FOnlineSessionSettings> LastSessionSettings;
//
// To add to the Online Session Interface delegate list.
// We'll bind our MultiplayerSessionsSubsystem internal callbacks to these.
//
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
FDelegateHandle CreateSessionCompleteDelegateHandle;
FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;
FDelegateHandle FindSessionsCompleteDelegateHandle;
FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;
FDelegateHandle JoinSessionCompleteDelegateHandle;
FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate;
FDelegateHandle DestroySessionCompleteDelegateHandle;
FOnStartSessionCompleteDelegate StartSessionCompleteDelegate;
FDelegateHandle StartSessionCompleteDelegateHandle;
};
변수 추가
- TSharedPtr<FOnlineSessionSettings> LastSessionSettings;
MultiplayerSessionsSubsystem.cpp
더보기
#include "MultiplayerSessionsSubsystem.h"
#include "OnlineSubsystem.h"
#include "OnlineSessionSettings.h"
UMultiplayerSessionsSubsystem::UMultiplayerSessionsSubsystem(): //Delegate을 만들어 On~함수에 연결한다.
CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateSessionComplete)),
FindSessionsCompleteDelegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnFindSessionsComplete)),
JoinSessionCompleteDelegate(FOnJoinSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnJoinSessionComplete)),
DestroySessionCompleteDelegate(FOnDestroySessionCompleteDelegate::CreateUObject(this, &ThisClass::OnDestroySessionComplete)),
StartSessionCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnStartSessionComplete))
{
IOnlineSubsystem* Subsystem = IOnlineSubsystem::Get();
if (Subsystem)
{
SessionInterface = Subsystem->GetSessionInterface();//SessionInterface 변수에 IOnlineSubsystem의 SessionInterface 정보를 담는다.
}
}
void UMultiplayerSessionsSubsystem::CreateSession(int32 NumPublicConnections, FString MatchType)
{
if (!SessionInterface.IsValid())
{
return;
}
//이미 존재하는 Session이 있다면 제거해준다.
auto ExistingSession = SessionInterface->GetNamedSession(NAME_GameSession);
if (ExistingSession != nullptr)
{
SessionInterface->DestroySession(NAME_GameSession);
}
// 새로 만드는 Session을 세팅해준다.
// FDelegateHandle 내에 delegate을 저장한다. 그리고 추후에 Delegate List에서 제거한다.
// Store the delegate in a FDelegateHandle so we can later remove it from the delegate list
CreateSessionCompleteDelegateHandle = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate);
LastSessionSettings = MakeShareable(new FOnlineSessionSettings());
LastSessionSettings->bIsLANMatch = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true : false;//Steam Subsystem에 연결하는 경우는 LAN Match가 아니다. NULL Subsystem을 사용하는 경우 LAN Match다.
LastSessionSettings->NumPublicConnections = NumPublicConnections;//함수 Input값을 적용. 접속 가능한 Players 수 제한
LastSessionSettings->bAllowJoinInProgress = true;//Session이 on going일 때 참가할 수 있게 설정. Session이 실행중일 때 Player들이 원할 때 들어올 수 있음
LastSessionSettings->bAllowJoinViaPresence = true;//Steam 기준에서 같은 region에 있는 Player들만 들어올 수 있게 설정.
LastSessionSettings->bShouldAdvertise = true;//Steam에서 Advertise가 가능하여 사람들이 찾아 들어올 수 있게 한다.
LastSessionSettings->bUsesPresence = true;//같은 region에서 session을 찾을 수 있게 해준다.
LastSessionSettings->Set(FName("MatchType"), MatchType, EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
if (false == SessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *LastSessionSettings))//CreateSession 리턴값이 false라면(=Session 만들기에 실패한다면)
{
//Delegate Handle를 사용하여 Delegate List에서 제거한다.
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
}
}
void UMultiplayerSessionsSubsystem::FindSessions(int32 MaxSearchResults)
{
}
void UMultiplayerSessionsSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionResult)
{
}
void UMultiplayerSessionsSubsystem::DestroySession()
{
}
void UMultiplayerSessionsSubsystem::StartSession()
{
}
void UMultiplayerSessionsSubsystem::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{
}
void UMultiplayerSessionsSubsystem::OnFindSessionsComplete(bool bWasSuccessful)
{
}
void UMultiplayerSessionsSubsystem::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
}
void UMultiplayerSessionsSubsystem::OnDestroySessionComplete(FName SessionName, bool bWasSuccessful)
{
}
void UMultiplayerSessionsSubsystem::OnStartSessionComplete(FName SessionName, bool bWasSuccessful)
{
}
헤더 추가
- #include "OnlineSessionSettings.h"
void UMultiplayerSessionsSubsystem::CreateSession(int32 NumPublicConnections, FString MatchType)
- CreateSessionCompleteDelegateHandle = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle (CreateSessionCompleteDelegate);
- 새로 만드는 Session을 세팅해준다. FDelegateHandle 내에 delegate을 저장한다. 그리고 추후에 Delegate List에서 제거한다.
- const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
- if (false == SessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *LastSessionSettings)) //CreateSession 리턴값이 false라면(=Session 만들기에 실패한다면)
- SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
- Delegate Handle를 사용하여 Delegate List에서 제거한다.
- SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
Travel to Lobby - Menu
Menu.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Menu.generated.h"
UCLASS()
class MULTIPLAYERSESSIONS_API UMenu : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void MenuSetup(int32 NumberOfPublicConnections = 4, FString TypeOfMatch = FString(TEXT("FreeForAll")));//접속할 수 있는 Player 숫자를 input으로 만들고 4를 기본값으로 설정한다.
protected:
virtual bool Initialize() override;
virtual void OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld) override;//다른 Level로 이동하면 기존의 Level을 지우는 함수.
private:
//meta = (BindWidget)을 사용하면 BP의 Button Widget이 아래의 변수와 연결된다. 이 때 BP와 C++변수 이름은 일치하여야 한다.
UPROPERTY(meta = (BindWidget))
class UButton* HostButton;
UPROPERTY(meta = (BindWidget))
UButton* JoinButton;
UFUNCTION()
void HostButtonClicked();
UFUNCTION()
void JoinButtonClicked();
void MenuTearDown();
// The subsystem designed to handle all online session functionality
class UMultiplayerSessionsSubsystem* MultiplayerSessionsSubsystem;
int32 NumPublicConnections{ 4 };
FString MatchType{ TEXT("FreeForAll") };
};
Menu.cpp
더보기
#include "Menu.h"
#include "Components/Button.h"
#include "MultiplayerSessionsSubsystem.h"
void UMenu::MenuSetup(int32 NumberOfPublicConnections, FString TypeOfMatch)
{
NumPublicConnections = NumberOfPublicConnections;
MatchType = TypeOfMatch;
AddToViewport();
SetVisibility(ESlateVisibility::Visible);
bIsFocusable = true;
UWorld* World = GetWorld();
if (World)
{
APlayerController* PlayerController = World->GetFirstPlayerController();
if (PlayerController)
{
FInputModeUIOnly InputModeData;
InputModeData.SetWidgetToFocus(TakeWidget());
InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
PlayerController->SetInputMode(InputModeData);
PlayerController->SetShowMouseCursor(true);
}
}
UGameInstance* GameInstance = GetGameInstance();
if (GameInstance)
{
//헤더에서 만든 MultiplayerSessionsSubsystem 변수에 Subsystem을 리턴 값을 넣어준다.
MultiplayerSessionsSubsystem = GameInstance->GetSubsystem<UMultiplayerSessionsSubsystem>();
}
}
bool UMenu::Initialize()
{
//Super버젼이 false면 false를 리턴한다.(=상위 클래스에서 Initialize 하는게 없으면 false를 리턴하여 Initialize()를 하지 않는다.)
if (!Super::Initialize())
{
return false;
}
if (HostButton)
{
//HostButton 클릭할 때 발생하는 이벤트를 Delegate로 연결해준다.
HostButton->OnClicked.AddDynamic(this, &ThisClass::HostButtonClicked);
}
if (JoinButton)
{
//JoinButton 클릭할 때 발생하는 이벤트를 Delegate로 연결해준다.
JoinButton->OnClicked.AddDynamic(this, &ThisClass::JoinButtonClicked);
}
return true;
}
void UMenu::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld)
{
MenuTearDown();//Widget을 뷰포트에서 지우고 input mode가 리셋된다.
Super::OnLevelRemovedFromWorld(InLevel, InWorld);
}
void UMenu::HostButtonClicked()
{
//디버깅 테스트
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
15.f,
FColor::Yellow,
FString(TEXT("Host Button Clicked"))
);
}
if (MultiplayerSessionsSubsystem)
{
MultiplayerSessionsSubsystem->CreateSession(NumPublicConnections, MatchType);//NumPublicConnections 숫자 크기까지 Players 접속 가능
UWorld* World = GetWorld();
if (World)
{
World->ServerTravel("/Game/ThirdPerson/Maps/Lobby?listen");
}
}
}
void UMenu::JoinButtonClicked()
{
//디버깅 테스트
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
15.f,
FColor::Yellow,
FString(TEXT("Join Button Clicked"))
);
}
}
void UMenu::MenuTearDown()
{
RemoveFromParent();
UWorld* World = GetWorld();
if (World)
{
APlayerController* PlayerController = World->GetFirstPlayerController();
if (PlayerController)
{
FInputModeGameOnly InputModeData;
PlayerController->SetInputMode(InputModeData);
PlayerController->SetShowMouseCursor(false);
}
}
}
BP_ThirdPersonCharacter
Event Graph
실행화면
Subsystem 기능들에 Callback 하기
구조
MultiplayerSessionSubsystem
MultiplayerSessionSubsystem.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Subsystems/GameInstanceSubsystem.h"
#include "Interfaces/OnlineSessionInterface.h"
#include "MultiplayerSessionsSubsystem.generated.h"
//
// Delcaring our own custom delegates for the Menu class to bind callbacks to
//
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnCreateSessionComplete, bool, bWasSuccessful);
UCLASS()
class MULTIPLAYERSESSIONS_API UMultiplayerSessionsSubsystem : public UGameInstanceSubsystem
{
GENERATED_BODY()
public:
UMultiplayerSessionsSubsystem();
//
// To handle session functionality. The Menu class will call these
//
void CreateSession(int32 NumPublicConnections, FString MatchType);
void FindSessions(int32 MaxSearchResults);
void JoinSession(const FOnlineSessionSearchResult& SessionResult);
void DestroySession();
void StartSession();
//
// Our own custom delegates for the Menu class to bind callbacks to
//
FMultiplayerOnCreateSessionComplete MultiplayerOnCreateSessionComplete;
protected:
// Internal callbacks for the delegates we'll add to the Online Session Interface delegate list.
// 아래의 함수들은 이 클래스 밖에서 콜하지 않는다.
void OnCreateSessionComplete(FName SessionName, bool bWasSuccessful);
void OnFindSessionsComplete(bool bWasSuccessful);
void OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result);
void OnDestroySessionComplete(FName SessionName, bool bWasSuccessful);
void OnStartSessionComplete(FName SessionName, bool bWasSuccessful);
private:
IOnlineSessionPtr SessionInterface;
TSharedPtr<FOnlineSessionSettings> LastSessionSettings;
//
// To add to the Online Session Interface delegate list.
// We'll bind our MultiplayerSessionsSubsystem internal callbacks to these.
//
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
FDelegateHandle CreateSessionCompleteDelegateHandle;
FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;
FDelegateHandle FindSessionsCompleteDelegateHandle;
FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;
FDelegateHandle JoinSessionCompleteDelegateHandle;
FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate;
FDelegateHandle DestroySessionCompleteDelegateHandle;
FOnStartSessionCompleteDelegate StartSessionCompleteDelegate;
FDelegateHandle StartSessionCompleteDelegateHandle;
};
Delegate
- DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnCreateSessionComplete, bool, bWasSuccessful);
- Delcaring our own custom delegates for the Menu class to bind callbacks to
Delegate 연결을 위한 변수 추가
- FMultiplayerOnCreateSessionComplete MultiplayerOnCreateSessionComplete;
MultiplayerSessionSubsystem.cpp
더보기
#include "MultiplayerSessionsSubsystem.h"
#include "OnlineSubsystem.h"
#include "OnlineSessionSettings.h"
UMultiplayerSessionsSubsystem::UMultiplayerSessionsSubsystem(): //Delegate을 만들어 On~함수에 연결한다.
CreateSessionCompleteDelegate(FOnCreateSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnCreateSessionComplete)),
FindSessionsCompleteDelegate(FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnFindSessionsComplete)),
JoinSessionCompleteDelegate(FOnJoinSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnJoinSessionComplete)),
DestroySessionCompleteDelegate(FOnDestroySessionCompleteDelegate::CreateUObject(this, &ThisClass::OnDestroySessionComplete)),
StartSessionCompleteDelegate(FOnStartSessionCompleteDelegate::CreateUObject(this, &ThisClass::OnStartSessionComplete))
{
IOnlineSubsystem* Subsystem = IOnlineSubsystem::Get();
if (Subsystem)
{
SessionInterface = Subsystem->GetSessionInterface();//SessionInterface 변수에 IOnlineSubsystem의 SessionInterface 정보를 담는다.
}
}
void UMultiplayerSessionsSubsystem::CreateSession(int32 NumPublicConnections, FString MatchType)
{
if (!SessionInterface.IsValid())
{
return;
}
//이미 존재하는 Session이 있다면 제거해준다.
auto ExistingSession = SessionInterface->GetNamedSession(NAME_GameSession);
if (ExistingSession != nullptr)
{
SessionInterface->DestroySession(NAME_GameSession);
}
// 새로 만드는 Session을 세팅해준다.
// FDelegateHandle 내에 delegate을 저장한다. 그리고 추후에 Delegate List에서 제거한다.
// Store the delegate in a FDelegateHandle so we can later remove it from the delegate list
CreateSessionCompleteDelegateHandle = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegate);
LastSessionSettings = MakeShareable(new FOnlineSessionSettings());
LastSessionSettings->bIsLANMatch = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true : false;//Steam Subsystem에 연결하는 경우는 LAN Match가 아니다. NULL Subsystem을 사용하는 경우 LAN Match다.
LastSessionSettings->NumPublicConnections = NumPublicConnections;//함수 Input값을 적용. 접속 가능한 Players 수 제한
LastSessionSettings->bAllowJoinInProgress = true;//Session이 on going일 때 참가할 수 있게 설정. Session이 실행중일 때 Player들이 원할 때 들어올 수 있음
LastSessionSettings->bAllowJoinViaPresence = true;//Steam 기준에서 같은 region에 있는 Player들만 들어올 수 있게 설정.
LastSessionSettings->bShouldAdvertise = true;//Steam에서 Advertise가 가능하여 사람들이 찾아 들어올 수 있게 한다.
LastSessionSettings->bUsesPresence = true;//같은 region에서 session을 찾을 수 있게 해준다.
LastSessionSettings->Set(FName("MatchType"), MatchType, EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
if (false == SessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *LastSessionSettings))//CreateSession 리턴값이 false라면(=Session 만들기에 실패한다면)
{
//Delegate Handle를 사용하여 Delegate List에서 제거한다.
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
// 헤더에서 만든 MultiplayerOnCreateSessionComplete delegate을 Broadcast 해준다.
// Broadcast our own custom delegate
MultiplayerOnCreateSessionComplete.Broadcast(false);//위의 if조건에서는 false
}
}
void UMultiplayerSessionsSubsystem::FindSessions(int32 MaxSearchResults)
{
}
void UMultiplayerSessionsSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionResult)
{
}
void UMultiplayerSessionsSubsystem::DestroySession()
{
}
void UMultiplayerSessionsSubsystem::StartSession()
{
}
void UMultiplayerSessionsSubsystem::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
{
//SessionInterfaces의 Delegate을 지워준다.
if (SessionInterface)
{
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
}
//MultiplayerOnCreateSessionComplete delegate를 Broadcast 해준다. 이렇게하면 Menu 클래스는 callback function 가지게 된다.
MultiplayerOnCreateSessionComplete.Broadcast(bWasSuccessful);
}
void UMultiplayerSessionsSubsystem::OnFindSessionsComplete(bool bWasSuccessful)
{
}
void UMultiplayerSessionsSubsystem::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
{
}
void UMultiplayerSessionsSubsystem::OnDestroySessionComplete(FName SessionName, bool bWasSuccessful)
{
}
void UMultiplayerSessionsSubsystem::OnStartSessionComplete(FName SessionName, bool bWasSuccessful)
{
}
Menu
Menu.h
더보기
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "Menu.generated.h"
UCLASS()
class MULTIPLAYERSESSIONS_API UMenu : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void MenuSetup(int32 NumberOfPublicConnections = 4, FString TypeOfMatch = FString(TEXT("FreeForAll")));//접속할 수 있는 Player 숫자를 input으로 만들고 4를 기본값으로 설정한다.
protected:
virtual bool Initialize() override;
virtual void OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld) override;//다른 Level로 이동하면 기존의 Level을 지우는 함수.
//
// Callbacks for the custom delegates on the MultiplayerSessionsSubsystem
// MultiplayerSessionsSubsystem.h의 Dynamic Delegate과 연결된다. Dynamic과 연결되는 경우 UFUNCTION()을 꼭 붙여야 한다. 붙이지 않으면 dynamic delegate과 연결되지 않는다.
UFUNCTION()
void OnCreateSession(bool bWasSuccessful);
private:
//meta = (BindWidget)을 사용하면 BP의 Button Widget이 아래의 변수와 연결된다. 이 때 BP와 C++변수 이름은 일치하여야 한다.
UPROPERTY(meta = (BindWidget))
class UButton* HostButton;
UPROPERTY(meta = (BindWidget))
UButton* JoinButton;
UFUNCTION()
void HostButtonClicked();
UFUNCTION()
void JoinButtonClicked();
void MenuTearDown();
// The subsystem designed to handle all online session functionality
class UMultiplayerSessionsSubsystem* MultiplayerSessionsSubsystem;
int32 NumPublicConnections{ 4 };
FString MatchType{ TEXT("FreeForAll") };
};
함수 추가
- UFUNCTION()
void OnCreateSession(bool bWasSuccessful);- Callbacks for the custom delegates on the MultiplayerSessionsSubsystem
Menu.cpp
더보기
#include "Menu.h"
#include "Components/Button.h"
#include "MultiplayerSessionsSubsystem.h"
void UMenu::MenuSetup(int32 NumberOfPublicConnections, FString TypeOfMatch)
{
NumPublicConnections = NumberOfPublicConnections;
MatchType = TypeOfMatch;
AddToViewport();
SetVisibility(ESlateVisibility::Visible);
bIsFocusable = true;
UWorld* World = GetWorld();
if (World)
{
APlayerController* PlayerController = World->GetFirstPlayerController();
if (PlayerController)
{
FInputModeUIOnly InputModeData;
InputModeData.SetWidgetToFocus(TakeWidget());
InputModeData.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
PlayerController->SetInputMode(InputModeData);
PlayerController->SetShowMouseCursor(true);
}
}
UGameInstance* GameInstance = GetGameInstance();
if (GameInstance)
{
//헤더에서 만든 MultiplayerSessionsSubsystem 변수에 Subsystem을 리턴 값을 넣어준다.
MultiplayerSessionsSubsystem = GameInstance->GetSubsystem<UMultiplayerSessionsSubsystem>();
}
if (MultiplayerSessionsSubsystem)
{
//callback을 Bind해준다.
MultiplayerSessionsSubsystem->MultiplayerOnCreateSessionComplete.AddDynamic(this, &ThisClass::OnCreateSession);
}
}
bool UMenu::Initialize()
{
//Super버젼이 false면 false를 리턴한다.(=상위 클래스에서 Initialize 하는게 없으면 false를 리턴하여 Initialize()를 하지 않는다.)
if (!Super::Initialize())
{
return false;
}
if (HostButton)
{
//HostButton 클릭할 때 발생하는 이벤트를 Delegate로 연결해준다.
HostButton->OnClicked.AddDynamic(this, &ThisClass::HostButtonClicked);
}
if (JoinButton)
{
//JoinButton 클릭할 때 발생하는 이벤트를 Delegate로 연결해준다.
JoinButton->OnClicked.AddDynamic(this, &ThisClass::JoinButtonClicked);
}
return true;
}
void UMenu::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld)
{
MenuTearDown();//Widget을 뷰포트에서 지우고 input mode가 리셋된다.
Super::OnLevelRemovedFromWorld(InLevel, InWorld);
}
void UMenu::OnCreateSession(bool bWasSuccessful)
{
if (bWasSuccessful)
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
15.f,
FColor::Yellow,
FString(TEXT("Session created successfully!"))
);
}
UWorld* World = GetWorld();
if (World)
{
World->ServerTravel("/Game/ThirdPerson/Maps/Lobby?listen");
}
}
else//실패한 경우
{
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
15.f,
FColor::Red,
FString(TEXT("Failed to create session!"))
);
}
}
}
void UMenu::HostButtonClicked()
{
if (MultiplayerSessionsSubsystem)
{
MultiplayerSessionsSubsystem->CreateSession(NumPublicConnections, MatchType);//NumPublicConnections 숫자 크기까지 Players 접속 가능
UWorld* World = GetWorld();
}
}
void UMenu::JoinButtonClicked()
{
//디버깅 테스트
if (GEngine)
{
GEngine->AddOnScreenDebugMessage(
-1,
15.f,
FColor::Yellow,
FString(TEXT("Join Button Clicked"))
);
}
}
void UMenu::MenuTearDown()
{
RemoveFromParent();
UWorld* World = GetWorld();
if (World)
{
APlayerController* PlayerController = World->GetFirstPlayerController();
if (PlayerController)
{
FInputModeGameOnly InputModeData;
PlayerController->SetInputMode(InputModeData);
PlayerController->SetShowMouseCursor(false);
}
}
}
void UMenu::MenuSetup(int32 NumberOfPublicConnections, FString TypeOfMatch)
- if (MultiplayerSessionsSubsystem) {
MultiplayerSessionsSubsystem->MultiplayerOnCreateSessionComplete.AddDynamic(this, &ThisClass:: OnCreateSession); }
레퍼런스 주소를 잘 기입해야 한다.
- World->ServerTravel("/Game/ThirdPerson/Maps/Lobby?listen");
실행화면
'⭐ Unreal Engine > UE Multiplayer FPS TPS + ListenServer' 카테고리의 다른 글
[UE] Multiplayer 8: Menu에서 Session 참가(Join)하기 (0) | 2023.07.17 |
---|---|
[UE] Multiplayer 7-2: Subsystem Delegate 연결하기 (0) | 2023.07.17 |
[UE] Multiplayer 6: Button Callbacks 만들기, SubSystem 접근하기 (0) | 2023.07.17 |
[UE] Multiplayer 5: Plugin: Plugin 만들기, Menu 생성하기 (0) | 2023.07.16 |
[UE] Multiplayer 4: Session 들어가기 (0) | 2023.07.15 |
댓글
이 글 공유하기
다른 글
-
[UE] Multiplayer 8: Menu에서 Session 참가(Join)하기
[UE] Multiplayer 8: Menu에서 Session 참가(Join)하기
2023.07.17 -
[UE] Multiplayer 7-2: Subsystem Delegate 연결하기
[UE] Multiplayer 7-2: Subsystem Delegate 연결하기
2023.07.17 -
[UE] Multiplayer 6: Button Callbacks 만들기, SubSystem 접근하기
[UE] Multiplayer 6: Button Callbacks 만들기, SubSystem 접근하기
2023.07.17 -
[UE] Multiplayer 5: Plugin: Plugin 만들기, Menu 생성하기
[UE] Multiplayer 5: Plugin: Plugin 만들기, Menu 생성하기
2023.07.16