Added MultiplayerSessions plugin
This commit is contained in:
parent
1ae803ce06
commit
92f264a78f
|
@ -51,6 +51,7 @@ SourceArt/**/*.tga
|
||||||
# Binary Files
|
# Binary Files
|
||||||
Binaries/*
|
Binaries/*
|
||||||
Plugins/*/Binaries/*
|
Plugins/*/Binaries/*
|
||||||
|
Plugins/Developer/
|
||||||
|
|
||||||
# Builds
|
# Builds
|
||||||
Build/*
|
Build/*
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"FileVersion": 3,
|
||||||
|
"Version": 1,
|
||||||
|
"VersionName": "1.0",
|
||||||
|
"FriendlyName": "MultiplayerSessions",
|
||||||
|
"Description": "A plugin for handling online multiplayer sessions",
|
||||||
|
"Category": "Other",
|
||||||
|
"CreatedBy": "Bert",
|
||||||
|
"CreatedByURL": "",
|
||||||
|
"DocsURL": "",
|
||||||
|
"MarketplaceURL": "",
|
||||||
|
"SupportURL": "",
|
||||||
|
"CanContainContent": true,
|
||||||
|
"IsBetaVersion": false,
|
||||||
|
"IsExperimentalVersion": false,
|
||||||
|
"Installed": false,
|
||||||
|
"Modules": [
|
||||||
|
{
|
||||||
|
"Name": "MultiplayerSessions",
|
||||||
|
"Type": "Runtime",
|
||||||
|
"LoadingPhase": "Default"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Plugins": [
|
||||||
|
{
|
||||||
|
"Name": "OnlineSubsystem",
|
||||||
|
"Enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "OnlineSubsystemSteam",
|
||||||
|
"Enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
|
@ -0,0 +1,58 @@
|
||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
using UnrealBuildTool;
|
||||||
|
|
||||||
|
public class MultiplayerSessions : ModuleRules
|
||||||
|
{
|
||||||
|
public MultiplayerSessions(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
|
PublicIncludePaths.AddRange(
|
||||||
|
new string[] {
|
||||||
|
// ... add public include paths required here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PrivateIncludePaths.AddRange(
|
||||||
|
new string[] {
|
||||||
|
// ... add other private include paths required here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PublicDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"Core",
|
||||||
|
"OnlineSubsystem",
|
||||||
|
"OnlineSubsystemSteam",
|
||||||
|
"UMG",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore"
|
||||||
|
// ... add other public dependencies that you statically link with here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PrivateDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"CoreUObject",
|
||||||
|
"Engine",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore"
|
||||||
|
// ... add private dependencies that you statically link with here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
DynamicallyLoadedModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
// ... add any modules that your module loads dynamically here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "Menu.h"
|
||||||
|
#include "Components/Button.h"
|
||||||
|
#include "MultiplayerSessionsSubsystem.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
#include "OnlineSubsystem.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 (GetGameInstance())
|
||||||
|
{
|
||||||
|
MultiplayerSessionsSubsystem = GameInstance->GetSubsystem<UMultiplayerSessionsSubsystem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MultiplayerSessionsSubsystem != nullptr)
|
||||||
|
{
|
||||||
|
MultiplayerSessionsSubsystem->MultiplayerOnCreateSessionComplete.AddDynamic(this, &ThisClass::OnCreateSession);
|
||||||
|
MultiplayerSessionsSubsystem->MultiplayerOnFindSessionsComplete.AddUObject(this, &ThisClass::OnFindSessions);
|
||||||
|
MultiplayerSessionsSubsystem->MultiplayerOnJoinSessionComplete.AddUObject(this, &ThisClass::OnJoinSession);
|
||||||
|
MultiplayerSessionsSubsystem->MultiplayerOnDestroySessionComplete.AddDynamic(this, &ThisClass::OnDestroySession);
|
||||||
|
MultiplayerSessionsSubsystem->MultiplayerOnStartSessionComplete.AddDynamic(this, &ThisClass::OnStartSession);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UMenu::Initialize()
|
||||||
|
{
|
||||||
|
if (!Super::Initialize())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HostButton)
|
||||||
|
{
|
||||||
|
HostButton->OnClicked.AddDynamic(this, &UMenu::HostButtonClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JoinButton)
|
||||||
|
{
|
||||||
|
JoinButton->OnClicked.AddDynamic(this, &UMenu::JoinButtonClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld)
|
||||||
|
{
|
||||||
|
MenuTearDown();
|
||||||
|
|
||||||
|
Super::OnLevelRemovedFromWorld(InLevel, InWorld);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::OnCreateSession(bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (GEngine)
|
||||||
|
{
|
||||||
|
GEngine->AddOnScreenDebugMessage(
|
||||||
|
-1,
|
||||||
|
15.f,
|
||||||
|
FColor::Green,
|
||||||
|
FString(TEXT("Session created successfully!")));
|
||||||
|
}
|
||||||
|
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if (World)
|
||||||
|
{
|
||||||
|
World->ServerTravel(FString("/Game/ThirdPerson/Maps/Lobby?listen"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (GEngine)
|
||||||
|
{
|
||||||
|
GEngine->AddOnScreenDebugMessage(
|
||||||
|
-1,
|
||||||
|
15.f,
|
||||||
|
FColor::Red,
|
||||||
|
FString(TEXT("Failed to create session!")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::OnFindSessions(const TArray<FOnlineSessionSearchResult>& SessionResults, bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (MultiplayerSessionsSubsystem == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto Result : SessionResults)
|
||||||
|
{
|
||||||
|
FString SettingsValue;
|
||||||
|
Result.Session.SessionSettings.Get(FName("MatchType"), SettingsValue);
|
||||||
|
if (SettingsValue == MatchType)
|
||||||
|
{
|
||||||
|
MultiplayerSessionsSubsystem->JoinSession(Result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::OnJoinSession(EOnJoinSessionCompleteResult::Type Result)
|
||||||
|
{
|
||||||
|
IOnlineSubsystem* Subsystem = IOnlineSubsystem::Get();
|
||||||
|
if (Subsystem)
|
||||||
|
{
|
||||||
|
IOnlineSessionPtr SessionInterface = Subsystem->GetSessionInterface();
|
||||||
|
|
||||||
|
if (SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
FString Address;
|
||||||
|
SessionInterface->GetResolvedConnectString(NAME_GameSession, Address);
|
||||||
|
|
||||||
|
APlayerController* PlayerController = GetGameInstance()->GetFirstLocalPlayerController();
|
||||||
|
if (PlayerController)
|
||||||
|
{
|
||||||
|
PlayerController->ClientTravel(Address, ETravelType::TRAVEL_Absolute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::OnDestroySession(bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::OnStartSession(bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::HostButtonClicked()
|
||||||
|
{
|
||||||
|
if (MultiplayerSessionsSubsystem)
|
||||||
|
{
|
||||||
|
MultiplayerSessionsSubsystem->CreateSession(NumPublicConnections, MatchType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::JoinButtonClicked()
|
||||||
|
{
|
||||||
|
if (MultiplayerSessionsSubsystem)
|
||||||
|
{
|
||||||
|
MultiplayerSessionsSubsystem->FindSessions(10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMenu::MenuTearDown()
|
||||||
|
{
|
||||||
|
RemoveFromParent();
|
||||||
|
UWorld* World = GetWorld();
|
||||||
|
if (World)
|
||||||
|
{
|
||||||
|
APlayerController* PlayerController = World->GetFirstPlayerController();
|
||||||
|
if (PlayerController)
|
||||||
|
{
|
||||||
|
FInputModeGameOnly InputModeData;
|
||||||
|
PlayerController->SetInputMode(InputModeData);
|
||||||
|
PlayerController->SetShowMouseCursor(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#include "MultiplayerSessions.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FMultiplayerSessionsModule"
|
||||||
|
|
||||||
|
void FMultiplayerSessionsModule::StartupModule()
|
||||||
|
{
|
||||||
|
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||||
|
}
|
||||||
|
|
||||||
|
void FMultiplayerSessionsModule::ShutdownModule()
|
||||||
|
{
|
||||||
|
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||||
|
// we call this function before unloading the module.
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(FMultiplayerSessionsModule, MultiplayerSessions)
|
|
@ -0,0 +1,153 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "MultiplayerSessionsSubsystem.h"
|
||||||
|
|
||||||
|
#include "OnlineSubsystem.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
|
||||||
|
UMultiplayerSessionsSubsystem::UMultiplayerSessionsSubsystem():
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::CreateSession(int32 NumPublicConnections, FString MatchType)
|
||||||
|
{
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ExistingSession = SessionInterface->GetNamedSession(NAME_GameSession);
|
||||||
|
if (ExistingSession != nullptr)
|
||||||
|
{
|
||||||
|
SessionInterface->DestroySession(NAME_GameSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
LastSessionSettings->NumPublicConnections = NumPublicConnections;
|
||||||
|
LastSessionSettings->bAllowJoinInProgress = true;
|
||||||
|
LastSessionSettings->bAllowJoinViaPresence = true;
|
||||||
|
LastSessionSettings->bShouldAdvertise = true;
|
||||||
|
LastSessionSettings->bUsesPresence = true;
|
||||||
|
LastSessionSettings->bUseLobbiesIfAvailable = true; // For UE5 when not finding sessions
|
||||||
|
LastSessionSettings->Set(FName("MatchType"), FString(MatchType), EOnlineDataAdvertisementType::ViaOnlineServiceAndPing);
|
||||||
|
LastSessionSettings->BuildUniqueId = 1;
|
||||||
|
|
||||||
|
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
||||||
|
if (!SessionInterface->CreateSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, *LastSessionSettings))
|
||||||
|
{
|
||||||
|
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
// Broadcast our own custom delegate
|
||||||
|
MultiplayerOnCreateSessionComplete.Broadcast(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::FindSessions(int32 MaxSearchResults)
|
||||||
|
{
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindSessionCompleteDelegateHandle = SessionInterface->AddOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegate);
|
||||||
|
|
||||||
|
LastSessionSearch = MakeShareable(new FOnlineSessionSearch);
|
||||||
|
LastSessionSearch->MaxSearchResults = MaxSearchResults;
|
||||||
|
LastSessionSearch->bIsLanQuery = IOnlineSubsystem::Get()->GetSubsystemName() == "NULL" ? true : false;
|
||||||
|
LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
||||||
|
if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef()))
|
||||||
|
{
|
||||||
|
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
MultiplayerOnFindSessionsComplete.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionResult)
|
||||||
|
{
|
||||||
|
if (!SessionInterface.IsValid())
|
||||||
|
{
|
||||||
|
MultiplayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegate);
|
||||||
|
|
||||||
|
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
||||||
|
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, SessionResult))
|
||||||
|
{
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
MultiplayerOnJoinSessionComplete.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::DestroySession()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::StartSession()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::OnCreateSessionComplete(FName SessionName, bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (SessionInterface)
|
||||||
|
{
|
||||||
|
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiplayerOnCreateSessionComplete.Broadcast(bWasSuccessful);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::OnFindSessionsComplete(bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
if (SessionInterface)
|
||||||
|
{
|
||||||
|
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LastSessionSearch->SearchResults.Num() <= 0)
|
||||||
|
{
|
||||||
|
MultiplayerOnFindSessionsComplete.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiplayerOnFindSessionsComplete.Broadcast(LastSessionSearch->SearchResults, bWasSuccessful);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::OnJoinSessionComplete(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
|
||||||
|
{
|
||||||
|
if (SessionInterface)
|
||||||
|
{
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiplayerOnJoinSessionComplete.Broadcast(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::OnDestroySessionComplete(FName SessionName, bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMultiplayerSessionsSubsystem::OnStartSessionComplete(FName SessionNAme, bool bWasSuccessful)
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Blueprint/UserWidget.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.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")));
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual bool Initialize() override;
|
||||||
|
virtual void OnLevelRemovedFromWorld(ULevel* InLevel, UWorld* InWorld) override;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callbacks fot the custom delegates on the MultiplayerSessionsSubsystem
|
||||||
|
*/
|
||||||
|
UFUNCTION()
|
||||||
|
void OnCreateSession(bool bWasSuccessful);
|
||||||
|
void OnFindSessions(const TArray<FOnlineSessionSearchResult>& SessionResults, bool bWasSuccessful);
|
||||||
|
void OnJoinSession(EOnJoinSessionCompleteResult::Type Result);
|
||||||
|
UFUNCTION()
|
||||||
|
void OnDestroySession(bool bWasSuccessful);
|
||||||
|
UFUNCTION()
|
||||||
|
void OnStartSession(bool bWasSuccessful);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
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")};
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class FMultiplayerSessionsModule : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** IModuleInterface implementation */
|
||||||
|
virtual void StartupModule() override;
|
||||||
|
virtual void ShutdownModule() override;
|
||||||
|
};
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
#include "Subsystems/GameInstanceSubsystem.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "MultiplayerSessionsSubsystem.generated.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Declaring our own custom delegates for the Menu class to bind callbacks to
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnCreateSessionComplete, bool, bWasSuccessful);
|
||||||
|
DECLARE_MULTICAST_DELEGATE_TwoParams(FMultiplayerOnFindSessionsComplete, const TArray<FOnlineSessionSearchResult>& SessionResults, bool bWasSuccessful);
|
||||||
|
DECLARE_MULTICAST_DELEGATE_OneParam(FMultiplayerOnJoinSessionComplete, EOnJoinSessionCompleteResult::Type Result)
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnDestroySessionComplete, bool, bWasSuccessful);
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMultiplayerOnStartSessionComplete, 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;
|
||||||
|
FMultiplayerOnFindSessionsComplete MultiplayerOnFindSessionsComplete;
|
||||||
|
FMultiplayerOnJoinSessionComplete MultiplayerOnJoinSessionComplete;
|
||||||
|
FMultiplayerOnDestroySessionComplete MultiplayerOnDestroySessionComplete;
|
||||||
|
FMultiplayerOnStartSessionComplete MultiplayerOnStartSessionComplete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal callbacks for the delegates we'll add to the Online Session Interface delegate list.
|
||||||
|
* These don't need to be called outside this class
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
TSharedPtr<FOnlineSessionSearch> LastSessionSearch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To add to the Online Session Interface delegate list.
|
||||||
|
* We'll bind our MultiplayerSessionSubsystem internal callbacks to these.
|
||||||
|
*/
|
||||||
|
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
|
||||||
|
FDelegateHandle CreateSessionCompleteDelegateHandle;
|
||||||
|
FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;
|
||||||
|
FDelegateHandle FindSessionCompleteDelegateHandle;
|
||||||
|
FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;
|
||||||
|
FDelegateHandle JoinSessionCompleteDelegateHandle;
|
||||||
|
FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate;
|
||||||
|
FDelegateHandle DestroySessionCompleteDelegateHandle;
|
||||||
|
FOnStartSessionCompleteDelegate StartSessionCompleteDelegate;
|
||||||
|
FDelegateHandle StartSessionCompleteDelegateHandle;
|
||||||
|
};
|
Loading…
Reference in New Issue