parent
efa99f3fd7
commit
d7b7c46cd5
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,35 +1,34 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
#include "MyPawn.h"
|
#include "BattlePawn.h"
|
||||||
|
|
||||||
|
|
||||||
// Sets default values
|
// Sets default values
|
||||||
AMyPawn::AMyPawn() {
|
ABattlePawn::ABattlePawn() {
|
||||||
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||||
PrimaryActorTick.bCanEverTick = true;
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the game starts or when spawned
|
// Called when the game starts or when spawned
|
||||||
void AMyPawn::BeginPlay() {
|
void ABattlePawn::BeginPlay() {
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMyPawn::MoveForward(float Val) {
|
void ABattlePawn::MoveForward(float Val) {
|
||||||
if (Val != 0.f)
|
if (Val != 0.f) {
|
||||||
{
|
if (Controller) {
|
||||||
if (Controller)
|
|
||||||
{
|
|
||||||
FRotator ControlSpaceRot = Controller->GetControlRotation();
|
FRotator ControlSpaceRot = Controller->GetControlRotation();
|
||||||
ControlSpaceRot.Pitch = 0;
|
ControlSpaceRot.Pitch = 0;
|
||||||
|
|
||||||
// transform to world space and add it
|
// transform to world space and add it
|
||||||
AddMovementInput( FRotationMatrix(ControlSpaceRot).GetScaledAxis( EAxis::X ), Val );
|
AddMovementInput(
|
||||||
|
FRotationMatrix(ControlSpaceRot).GetScaledAxis(EAxis::X), Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called to bind functionality to input
|
// Called to bind functionality to input
|
||||||
void AMyPawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) {
|
void ABattlePawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) {
|
||||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
#include "MyPlayerStart.h"
|
#include "BattlePlayerStart.h"
|
||||||
|
|
||||||
uint8 AMyPlayerStart::GetPlayerIndex() const {
|
uint8 ABattlePlayerStart::GetPlayerIndex() const {
|
||||||
return PlayerIndex;
|
return PlayerIndex;
|
||||||
}
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "GameOverWidget.h"
|
||||||
|
#include "../SessionsGameInstanceSubsystem.h"
|
||||||
|
#include "Components/Button.h"
|
||||||
|
#include "Components/TextBlock.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
|
||||||
|
void UGameOverWidget::NativeConstruct() {
|
||||||
|
ButtonToMenu->OnClicked.AddDynamic(this, &ThisClass::QuitCurrentSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UGameOverWidget::QuitCurrentSession_Implementation() {
|
||||||
|
const UGameInstance *GameInstance = UGameplayStatics::GetGameInstance(
|
||||||
|
GetWorld());
|
||||||
|
USessionsGameInstanceSubsystem *GameInstanceSubsystem = GameInstance->GetSubsystem
|
||||||
|
<USessionsGameInstanceSubsystem>();
|
||||||
|
GameInstanceSubsystem->QuitCurrentSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UGameOverWidget::SetWidgetText_Implementation(bool HasWon) {
|
||||||
|
if (HasWon) {
|
||||||
|
GameOverText->SetText(FText::FromString("You won!"));
|
||||||
|
} else {
|
||||||
|
GameOverText->SetText(FText::FromString("You lose!"));
|
||||||
|
}
|
||||||
|
}
|
@ -1,34 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#include "GameOverWidget.h"
|
|
||||||
|
|
||||||
#include "MyGameInstanceSubsystem.h"
|
|
||||||
#include "Components/Button.h"
|
|
||||||
#include "Components/TextBlock.h"
|
|
||||||
#include "Kismet/GameplayStatics.h"
|
|
||||||
|
|
||||||
|
|
||||||
void UGameOverWidget::NativeConstruct()
|
|
||||||
{
|
|
||||||
ButtonToMenu->OnClicked.AddDynamic(this, &ThisClass::QuitCurrentSession);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UGameOverWidget::QuitCurrentSession()
|
|
||||||
{
|
|
||||||
const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(GetWorld());
|
|
||||||
UMyGameInstanceSubsystem* GameInstanceSubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();
|
|
||||||
GameInstanceSubsystem->QuitCurrentSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UGameOverWidget::SetWidgetText_Implementation(bool HasWon)
|
|
||||||
{
|
|
||||||
if (HasWon)
|
|
||||||
{
|
|
||||||
GameOverText->SetText(FText::FromString("You won!"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GameOverText->SetText(FText::FromString("You lose!"));
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,34 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "MainMenuWidget.h"
|
||||||
|
#include "Components/Button.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
void UMainMenuWidget::NativeConstruct() {
|
||||||
|
Super::NativeConstruct();
|
||||||
|
|
||||||
|
HostOnlineGameButton->OnClicked.AddDynamic(
|
||||||
|
this, &ThisClass::UMainMenuWidget::OnHostOnlineGameButtonClicked);
|
||||||
|
|
||||||
|
GetMyGameSubsystem()->OnCreateSessionCompleteEvent.AddDynamic(
|
||||||
|
this, &ThisClass::StartSessionWhenCreatingSessonComplete);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMainMenuWidget::OnHostOnlineGameButtonClicked() {
|
||||||
|
GetMyGameSubsystem()->CreateSession(
|
||||||
|
"Lobby " + FString::FromInt(FMath::RandRange(1, 1e6)), 2, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMainMenuWidget::StartSessionWhenCreatingSessonComplete(bool bSuccess) {
|
||||||
|
GetMyGameSubsystem()->StartSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
USessionsGameInstanceSubsystem *UMainMenuWidget::GetMyGameSubsystem() const {
|
||||||
|
const UGameInstance *GameInstance = UGameplayStatics::GetGameInstance(
|
||||||
|
GetWorld());
|
||||||
|
USessionsGameInstanceSubsystem *GameInstanceSubsystem = GameInstance->
|
||||||
|
GetSubsystem<USessionsGameInstanceSubsystem>();
|
||||||
|
return GameInstanceSubsystem;
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Blueprint/UserWidget.h"
|
||||||
|
#include "../SessionsGameInstanceSubsystem.h"
|
||||||
|
|
||||||
|
#include "MainMenuWidget.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class TURNBASEDTUTORIAL_API UMainMenuWidget : public UUserWidget {
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(meta = (BindWidget))
|
||||||
|
class UButton *HostOnlineGameButton;
|
||||||
|
|
||||||
|
virtual void NativeConstruct() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
UFUNCTION()
|
||||||
|
void OnHostOnlineGameButtonClicked();
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void StartSessionWhenCreatingSessonComplete(bool bSuccess);
|
||||||
|
|
||||||
|
private:
|
||||||
|
USessionsGameInstanceSubsystem *GetMyGameSubsystem() const;
|
||||||
|
};
|
@ -0,0 +1,24 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "SessionListEntryWidget.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
#include "Components/TextBlock.h"
|
||||||
|
|
||||||
|
void USessionListEntryWidget::Update(int SessionIndex,
|
||||||
|
const FOnlineSessionSearchResult &
|
||||||
|
Session) {
|
||||||
|
SessionId = SessionIndex;
|
||||||
|
IndexText->SetText(FText::AsNumber(SessionIndex + 1));
|
||||||
|
|
||||||
|
Session.Session.SessionSettings.Get(SETTING_MAPNAME, SessionName);
|
||||||
|
SessionNameText->SetText(FText::FromString(SessionName));
|
||||||
|
|
||||||
|
const int MaxPlayerCount = Session.Session.SessionSettings.
|
||||||
|
NumPublicConnections;
|
||||||
|
const int CurPlayerCount = MaxPlayerCount - Session.Session.
|
||||||
|
NumOpenPublicConnections;
|
||||||
|
|
||||||
|
PlayersCountText->SetText(FText::AsNumber(CurPlayerCount));
|
||||||
|
PingText->SetText(FText::AsNumber(Session.PingInMs));
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Blueprint/UserWidget.h"
|
||||||
|
#include "SessionListEntryWidget.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class TURNBASEDTUTORIAL_API USessionListEntryWidget : public UUserWidget {
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
||||||
|
class UTextBlock *IndexText;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
||||||
|
class UTextBlock *SessionNameText;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
||||||
|
class UTextBlock *PlayersCountText;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
||||||
|
class UTextBlock *PingText;
|
||||||
|
|
||||||
|
void Update(int SessionIndex, const FOnlineSessionSearchResult &Session);
|
||||||
|
|
||||||
|
int SessionId;
|
||||||
|
FString SessionName;
|
||||||
|
};
|
@ -0,0 +1,80 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "SessionListWidget.h"
|
||||||
|
#include "../SessionsGameInstanceSubsystem.h"
|
||||||
|
#include "Components/VerticalBox.h"
|
||||||
|
#include "SessionListEntryWidget.h"
|
||||||
|
#include "Components/Button.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
void USessionListWidget::NativeConstruct() {
|
||||||
|
Super::NativeConstruct();
|
||||||
|
|
||||||
|
RefreshListButton->OnClicked.AddDynamic(
|
||||||
|
this, &ThisClass::OnRefreshListButtonClicked);
|
||||||
|
ConnectToSelectedSessionButton->OnClicked.AddDynamic(
|
||||||
|
this, &ThisClass::ConnectToFirstSession);
|
||||||
|
|
||||||
|
const auto MyGameInstanceSubsystem = GetMyGameSubsystem();
|
||||||
|
MyGameInstanceSubsystem->OnFindSessionsCompleteEvent.AddUObject(
|
||||||
|
this, &ThisClass::RefreshList);
|
||||||
|
MyGameInstanceSubsystem->OnJoinSessionCompleteEvent.AddUObject(
|
||||||
|
this, &ThisClass::OnJoinSessionSuccess);
|
||||||
|
|
||||||
|
// Initiate search
|
||||||
|
MyGameInstanceSubsystem->FindSessions(10, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USessionListWidget::RefreshList(
|
||||||
|
const TArray<FOnlineSessionSearchResult> &SessionResults,
|
||||||
|
bool bSuccessful) {
|
||||||
|
if (!bSuccessful) {
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("Find sessions FAILED!!!!"));
|
||||||
|
// TODO: Mark find sessions error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SessionListBox->ClearChildren();
|
||||||
|
for (const auto &Session : SessionResults) {
|
||||||
|
auto *ItemWidget = CreateWidget<USessionListEntryWidget>(
|
||||||
|
this, EntryClass);
|
||||||
|
ItemWidget->Update(SessionListBox->GetChildrenCount(), Session);
|
||||||
|
SessionListBox->AddChild(ItemWidget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionListWidget::OnRefreshListButtonClicked() {
|
||||||
|
// TODO: Show that we started searching...
|
||||||
|
// Initiate search
|
||||||
|
SessionListBox->ClearChildren();
|
||||||
|
GetMyGameSubsystem()->FindSessions(10, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USessionListWidget::ConnectToFirstSession() {
|
||||||
|
GetMyGameSubsystem()->JoinSession(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionListWidget::OnJoinSessionSuccess(
|
||||||
|
EOnJoinSessionCompleteResult::Type Result) {
|
||||||
|
if (Result != EOnJoinSessionCompleteResult::Success) {
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("Failed to connect to session!!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!GetMyGameSubsystem()->TryConnectToCurrentSession()) {
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("Failed to travel client to session!!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UE_LOG(LogTemp, Display, TEXT("Connected and travelled to session!!!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
USessionsGameInstanceSubsystem *
|
||||||
|
USessionListWidget::GetMyGameSubsystem() const {
|
||||||
|
const UGameInstance *GameInstance = UGameplayStatics::GetGameInstance(
|
||||||
|
GetWorld());
|
||||||
|
USessionsGameInstanceSubsystem *GameInstanceSubsystem = GameInstance->
|
||||||
|
GetSubsystem<USessionsGameInstanceSubsystem>();
|
||||||
|
return GameInstanceSubsystem;
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "../SessionsGameInstanceSubsystem.h"
|
||||||
|
#include "Blueprint/UserWidget.h"
|
||||||
|
#include "SessionListWidget.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class TURNBASEDTUTORIAL_API USessionListWidget : public UUserWidget {
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void NativeConstruct() override;
|
||||||
|
|
||||||
|
UPROPERTY(meta = (BindWidget))
|
||||||
|
class UButton *ConnectToSelectedSessionButton;
|
||||||
|
|
||||||
|
UPROPERTY(meta = (BindWidget))
|
||||||
|
class UButton *GoBackToMainMenuButton;
|
||||||
|
|
||||||
|
UPROPERTY(meta = (BindWidget))
|
||||||
|
class UButton *RefreshListButton;
|
||||||
|
|
||||||
|
UPROPERTY(meta = (BindWidget))
|
||||||
|
class UVerticalBox *SessionListBox;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, Category="Session Info Class")
|
||||||
|
TSubclassOf<class USessionListEntryWidget> EntryClass;
|
||||||
|
|
||||||
|
void RefreshList(const TArray<FOnlineSessionSearchResult> &SessionResults,
|
||||||
|
bool bSuccessful);
|
||||||
|
|
||||||
|
void OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
USessionsGameInstanceSubsystem *GetMyGameSubsystem() const;
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void OnRefreshListButtonClicked();
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void ConnectToFirstSession();
|
||||||
|
};
|
@ -1,368 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#include "MyGameInstanceSubsystem.h"
|
|
||||||
|
|
||||||
#include "MyPlayerController.h"
|
|
||||||
#include "OnlineSubsystemUtils.h"
|
|
||||||
#include "GameFramework/GameModeBase.h"
|
|
||||||
#include "Kismet/GameplayStatics.h"
|
|
||||||
|
|
||||||
UMyGameInstanceSubsystem::UMyGameInstanceSubsystem() : CreateSessionCompleteDelegate(
|
|
||||||
FOnCreateSessionCompleteDelegate::CreateUObject(
|
|
||||||
this, &ThisClass::OnCreateSessionCompleted)),
|
|
||||||
UpdateSessionCompleteDelegate(
|
|
||||||
FOnUpdateSessionCompleteDelegate::CreateUObject(
|
|
||||||
this, &ThisClass::OnUpdateSessionCompleted)),
|
|
||||||
StartSessionCompleteDelegate(
|
|
||||||
FOnStartSessionCompleteDelegate::CreateUObject(
|
|
||||||
this, &ThisClass::OnStartSessionCompleted)),
|
|
||||||
EndSessionCompleteDelegate(
|
|
||||||
FOnEndSessionCompleteDelegate::CreateUObject(
|
|
||||||
this, &ThisClass::OnEndSessionCompleted)),
|
|
||||||
DestroySessionCompleteDelegate(
|
|
||||||
FOnDestroySessionCompleteDelegate::CreateUObject(
|
|
||||||
this, &ThisClass::OnDestroySessionCompleted)),
|
|
||||||
FindSessionsCompleteDelegate(
|
|
||||||
FOnFindSessionsCompleteDelegate::CreateUObject(
|
|
||||||
this, &ThisClass::OnFindSessionsCompleted)),
|
|
||||||
JoinSessionCompleteDelegate(
|
|
||||||
FOnJoinSessionCompleteDelegate::CreateUObject(
|
|
||||||
this, &ThisClass::OnJoinSessionCompleted)),
|
|
||||||
bIsHost(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::CreateSession(FString SessionName, int32 NumPublicConnections, bool bIsLANMatch)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnCreateSessionCompleteEvent.Broadcast(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LastSessionSettings = MakeShareable(new FOnlineSessionSettings());
|
|
||||||
LastSessionSettings->NumPrivateConnections = 0;
|
|
||||||
LastSessionSettings->NumPublicConnections = NumPublicConnections;
|
|
||||||
LastSessionSettings->bAllowInvites = true;
|
|
||||||
LastSessionSettings->bAllowJoinInProgress = true;
|
|
||||||
LastSessionSettings->bAllowJoinViaPresence = true;
|
|
||||||
LastSessionSettings->bAllowJoinViaPresenceFriendsOnly = true;
|
|
||||||
LastSessionSettings->bUsesPresence = true;
|
|
||||||
LastSessionSettings->bIsLANMatch = bIsLANMatch;
|
|
||||||
LastSessionSettings->bShouldAdvertise = true;
|
|
||||||
|
|
||||||
LastSessionSettings->Set(SETTING_MAPNAME, SessionName,
|
|
||||||
EOnlineDataAdvertisementType::ViaOnlineService);
|
|
||||||
|
|
||||||
CreateSessionCompleteDelegateHandle = SessionInterface->AddOnCreateSessionCompleteDelegate_Handle(
|
|
||||||
CreateSessionCompleteDelegate);
|
|
||||||
|
|
||||||
const ULocalPlayer* localPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
|
||||||
if (!SessionInterface->CreateSession(*localPlayer->GetPreferredUniqueNetId(), NAME_GameSession,
|
|
||||||
*LastSessionSettings))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnCreateSessionCompleteEvent.Broadcast(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::OnCreateSessionCompleted(FName SessionName, bool bSuccessful)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(CreateSessionCompleteDelegateHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
bIsHost = true;
|
|
||||||
|
|
||||||
OnCreateSessionCompleteEvent.Broadcast(bSuccessful);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::UpdateSession()
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnCreateSessionCompleteEvent.Broadcast(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const TSharedPtr<FOnlineSessionSettings> UpdatedSessionSettings = MakeShareable(
|
|
||||||
new FOnlineSessionSettings(*LastSessionSettings));
|
|
||||||
|
|
||||||
// Here we can insert any changes we want
|
|
||||||
UpdatedSessionSettings->Set(SETTING_MAPNAME, FString("Updated Level Name"),
|
|
||||||
EOnlineDataAdvertisementType::ViaOnlineService);
|
|
||||||
|
|
||||||
UpdateSessionCompleteDelegateHandle =
|
|
||||||
SessionInterface->AddOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegate);
|
|
||||||
|
|
||||||
if (!SessionInterface->UpdateSession(NAME_GameSession, *UpdatedSessionSettings))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnUpdateSessionCompleteEvent.Broadcast(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LastSessionSettings = UpdatedSessionSettings;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::OnUpdateSessionCompleted(FName SessionName, bool bSuccessful)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr sessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (sessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
sessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(UpdateSessionCompleteDelegateHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnUpdateSessionCompleteEvent.Broadcast(bSuccessful);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::StartSession()
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnCreateSessionCompleteEvent.Broadcast(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
StartSessionCompleteDelegateHandle = SessionInterface->AddOnStartSessionCompleteDelegate_Handle(
|
|
||||||
StartSessionCompleteDelegate);
|
|
||||||
|
|
||||||
if (!SessionInterface->StartSession(NAME_GameSession))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnStartSessionCompleteEvent.Broadcast(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::OnStartSessionCompleted(FName SessionName, bool bSuccessful)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(StartSessionCompleteDelegateHandle);
|
|
||||||
}
|
|
||||||
OnStartSessionCompleteEvent.Broadcast(bSuccessful);
|
|
||||||
|
|
||||||
// TODO: Move this from gameinstance subsystem. This should not be here.
|
|
||||||
UGameplayStatics::OpenLevel(GetWorld(), "BattleFieldMap", true, "listen");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::EndSession()
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnCreateSessionCompleteEvent.Broadcast(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
EndSessionCompleteDelegateHandle = SessionInterface->AddOnEndSessionCompleteDelegate_Handle(
|
|
||||||
EndSessionCompleteDelegate);
|
|
||||||
|
|
||||||
if (!SessionInterface->EndSession(NAME_GameSession))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnEndSessionCompleteEvent.Broadcast(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::OnEndSessionCompleted(FName SessionName, bool bSuccessful)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnEndSessionCompleteEvent.Broadcast(bSuccessful);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::DestroySession()
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnDestroySessionCompleteEvent.Broadcast(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DestroySessionCompleteDelegateHandle = SessionInterface->AddOnDestroySessionCompleteDelegate_Handle(
|
|
||||||
DestroySessionCompleteDelegate);
|
|
||||||
|
|
||||||
if (!SessionInterface->DestroySession(NAME_GameSession))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(EndSessionCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnDestroySessionCompleteEvent.Broadcast(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::OnDestroySessionCompleted(FName SessionName, bool bSuccessful)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(DestroySessionCompleteDelegateHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnDestroySessionCompleteEvent.Broadcast(bSuccessful);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::FindSessions(int32 MaxSearchResults, bool bIsLANQuery)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnFindSessionsCompleteEvent.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FindSessionsCompleteDelegateHandle = SessionInterface->AddOnFindSessionsCompleteDelegate_Handle(
|
|
||||||
FindSessionsCompleteDelegate);
|
|
||||||
|
|
||||||
LastSessionSearch = MakeShareable(new FOnlineSessionSearch());
|
|
||||||
LastSessionSearch->MaxSearchResults = MaxSearchResults;
|
|
||||||
LastSessionSearch->bIsLanQuery = bIsLANQuery;
|
|
||||||
|
|
||||||
// Disable dedicated server search (maybe enable later, when dedicated server is implemented)
|
|
||||||
// LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
|
||||||
|
|
||||||
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
|
||||||
if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(), LastSessionSearch.ToSharedRef()))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnFindSessionsCompleteEvent.Broadcast(TArray<FOnlineSessionSearchResult>(), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::OnFindSessionsCompleted(bool bSuccessful)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(FindSessionsCompleteDelegateHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LastSessionSearch->SearchResults.Num() <= 0)
|
|
||||||
{
|
|
||||||
OnFindSessionsCompleteEvent.Broadcast(TArray<FOnlineSessionSearchResult>(), bSuccessful);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OnFindSessionsCompleteEvent.Broadcast(LastSessionSearch->SearchResults, bSuccessful);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::JoinSession(const FOnlineSessionSearchResult& SessionSearchResult)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(
|
|
||||||
JoinSessionCompleteDelegate);
|
|
||||||
|
|
||||||
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
|
||||||
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession, SessionSearchResult))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::JoinSession(const int32 Index)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!LastSessionSearch.IsValid() || Index >= LastSessionSearch->SearchResults.Num())
|
|
||||||
{
|
|
||||||
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JoinSessionCompleteDelegateHandle = SessionInterface->AddOnJoinSessionCompleteDelegate_Handle(
|
|
||||||
JoinSessionCompleteDelegate);
|
|
||||||
|
|
||||||
const ULocalPlayer* LocalPlayer = GetWorld()->GetFirstLocalPlayerFromController();
|
|
||||||
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(), NAME_GameSession,
|
|
||||||
LastSessionSearch->SearchResults[Index]))
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
|
|
||||||
|
|
||||||
OnJoinSessionCompleteEvent.Broadcast(EOnJoinSessionCompleteResult::UnknownError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::OnJoinSessionCompleted(FName SessionName, EOnJoinSessionCompleteResult::Type Result)
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(JoinSessionCompleteDelegateHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
OnJoinSessionCompleteEvent.Broadcast(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool UMyGameInstanceSubsystem::TryConnectToCurrentSession() const
|
|
||||||
{
|
|
||||||
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(GetWorld());
|
|
||||||
if (!SessionInterface.IsValid())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FString ConnectString;
|
|
||||||
if (!SessionInterface->GetResolvedConnectString(NAME_GameSession, ConnectString))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
|
|
||||||
PlayerController->ClientTravel(ConnectString, TRAVEL_Absolute);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMyGameInstanceSubsystem::QuitCurrentSession()
|
|
||||||
{
|
|
||||||
if (bIsHost)
|
|
||||||
{
|
|
||||||
UGameplayStatics::GetGameMode(GetWorld())->ReturnToMainMenuHost();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
APlayerController* LocalController = GEngine->GetFirstLocalPlayerController(GetWorld());
|
|
||||||
LocalController->ClientReturnToMainMenuWithTextReason(FText::FromString("Session ended"));
|
|
||||||
}
|
|
||||||
bIsHost = false;
|
|
||||||
DestroySession();
|
|
||||||
}
|
|
@ -1,107 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "OnlineSessionSettings.h"
|
|
||||||
|
|
||||||
#include "Interfaces/OnlineSessionInterface.h"
|
|
||||||
#include "Subsystems/GameInstanceSubsystem.h"
|
|
||||||
#include "MyGameInstanceSubsystem.generated.h"
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnCreateSessionComplete, bool, bSuccessful);
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnUpdateSessionComplete, bool, bSuccessful);
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnStartSessionCompete, bool, bSuccessful);
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnEndSessionComplete, bool, bSuccessful);
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnDestroySessionComplete, bool, bSuccessful);
|
|
||||||
|
|
||||||
DECLARE_MULTICAST_DELEGATE_TwoParams(FMyOnFindSessionsComplete,
|
|
||||||
const TArray<FOnlineSessionSearchResult>& SessionResults, bool bSuccessful);
|
|
||||||
|
|
||||||
DECLARE_MULTICAST_DELEGATE_OneParam(FMyOnJoinSessionCompele, EOnJoinSessionCompleteResult::Type Result);
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class TURNBASEDTUTORIAL_API UMyGameInstanceSubsystem : public UGameInstanceSubsystem
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UMyGameInstanceSubsystem();
|
|
||||||
|
|
||||||
void CreateSession(FString SessionName, int32 NumPublicConnections, bool bIsLANMatch);
|
|
||||||
|
|
||||||
void UpdateSession();
|
|
||||||
|
|
||||||
void StartSession();
|
|
||||||
|
|
||||||
void EndSession();
|
|
||||||
|
|
||||||
void DestroySession();
|
|
||||||
|
|
||||||
void FindSessions(int32 MaxSearchResults, bool bIsLANQuery);
|
|
||||||
|
|
||||||
void JoinSession(const FOnlineSessionSearchResult& SessionSearchResult);
|
|
||||||
|
|
||||||
void JoinSession(const int32 Index);
|
|
||||||
|
|
||||||
bool TryConnectToCurrentSession() const;
|
|
||||||
|
|
||||||
void QuitCurrentSession();
|
|
||||||
|
|
||||||
void UpdateSessionName(FString NewSessionName);
|
|
||||||
|
|
||||||
FMyOnCreateSessionComplete OnCreateSessionCompleteEvent;
|
|
||||||
FMyOnUpdateSessionComplete OnUpdateSessionCompleteEvent;
|
|
||||||
FMyOnStartSessionCompete OnStartSessionCompleteEvent;
|
|
||||||
FMyOnEndSessionComplete OnEndSessionCompleteEvent;
|
|
||||||
FMyOnDestroySessionComplete OnDestroySessionCompleteEvent;
|
|
||||||
FMyOnFindSessionsComplete OnFindSessionsCompleteEvent;
|
|
||||||
FMyOnJoinSessionCompele OnJoinSessionCompleteEvent;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void OnCreateSessionCompleted(FName SessionName, bool bSuccessful);
|
|
||||||
|
|
||||||
void OnUpdateSessionCompleted(FName SessionName, bool bSuccessful);
|
|
||||||
|
|
||||||
void OnStartSessionCompleted(FName SessionName, bool bSuccessful);
|
|
||||||
|
|
||||||
void OnEndSessionCompleted(FName SessionName, bool bSuccessful);
|
|
||||||
|
|
||||||
void OnDestroySessionCompleted(FName SessionName, bool bSuccessful);
|
|
||||||
|
|
||||||
void OnFindSessionsCompleted(bool bSuccessful);
|
|
||||||
|
|
||||||
void OnJoinSessionCompleted(FName SessionName, EOnJoinSessionCompleteResult::Type Result);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool bIsHost;
|
|
||||||
|
|
||||||
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
|
|
||||||
FDelegateHandle CreateSessionCompleteDelegateHandle;
|
|
||||||
TSharedPtr<FOnlineSessionSettings> LastSessionSettings;
|
|
||||||
|
|
||||||
FOnUpdateSessionCompleteDelegate UpdateSessionCompleteDelegate;
|
|
||||||
FDelegateHandle UpdateSessionCompleteDelegateHandle;
|
|
||||||
|
|
||||||
FOnStartSessionCompleteDelegate StartSessionCompleteDelegate;
|
|
||||||
FDelegateHandle StartSessionCompleteDelegateHandle;
|
|
||||||
|
|
||||||
FOnEndSessionCompleteDelegate EndSessionCompleteDelegate;
|
|
||||||
FDelegateHandle EndSessionCompleteDelegateHandle;
|
|
||||||
|
|
||||||
FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate;
|
|
||||||
FDelegateHandle DestroySessionCompleteDelegateHandle;
|
|
||||||
|
|
||||||
FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;
|
|
||||||
FDelegateHandle FindSessionsCompleteDelegateHandle;
|
|
||||||
TSharedPtr<FOnlineSessionSearch> LastSessionSearch;
|
|
||||||
|
|
||||||
FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;
|
|
||||||
FDelegateHandle JoinSessionCompleteDelegateHandle;
|
|
||||||
};
|
|
@ -1,35 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "MyMainMenu.h"
|
|
||||||
|
|
||||||
#include "Components/Button.h"
|
|
||||||
#include "Kismet/GameplayStatics.h"
|
|
||||||
|
|
||||||
void UMyMainMenu::NativeConstruct()
|
|
||||||
{
|
|
||||||
Super::NativeConstruct();
|
|
||||||
|
|
||||||
HostOnlineGameButton->OnClicked.AddDynamic(this, &ThisClass::UMyMainMenu::OnHostOnlineGameButtonClicked);
|
|
||||||
|
|
||||||
GetMyGameSubsystem()->OnCreateSessionCompleteEvent.AddDynamic(this, &ThisClass::StartSessionWhenCreatingSessonComplete);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMyMainMenu::OnHostOnlineGameButtonClicked()
|
|
||||||
{
|
|
||||||
GetMyGameSubsystem()->CreateSession("Lobby " + FString::FromInt(FMath::RandRange(1, 1e6)),2, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMyMainMenu::StartSessionWhenCreatingSessonComplete(bool bSuccess)
|
|
||||||
{
|
|
||||||
GetMyGameSubsystem()->StartSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UMyGameInstanceSubsystem* UMyMainMenu::GetMyGameSubsystem() const
|
|
||||||
{
|
|
||||||
const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(GetWorld());
|
|
||||||
UMyGameInstanceSubsystem* GameInstanceSubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();
|
|
||||||
return GameInstanceSubsystem;
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "Blueprint/UserWidget.h"
|
|
||||||
#include "MyGameInstanceSubsystem.h"
|
|
||||||
|
|
||||||
#include "MyMainMenu.generated.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class TURNBASEDTUTORIAL_API UMyMainMenu : public UUserWidget
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
|
||||||
class UButton* HostOnlineGameButton;
|
|
||||||
|
|
||||||
virtual void NativeConstruct() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
UFUNCTION()
|
|
||||||
void OnHostOnlineGameButtonClicked();
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void StartSessionWhenCreatingSessonComplete(bool bSuccess);
|
|
||||||
|
|
||||||
private:
|
|
||||||
UMyGameInstanceSubsystem* GetMyGameSubsystem() const;
|
|
||||||
};
|
|
@ -1,23 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "MySessionListEntryWidget.h"
|
|
||||||
|
|
||||||
#include "OnlineSessionSettings.h"
|
|
||||||
#include "Interfaces/OnlineSessionInterface.h"
|
|
||||||
#include "Components/TextBlock.h"
|
|
||||||
|
|
||||||
void UMySessionListEntryWidget::Update(int SessionIndex, const FOnlineSessionSearchResult& Session)
|
|
||||||
{
|
|
||||||
SessionId = SessionIndex;
|
|
||||||
IndexText->SetText(FText::AsNumber(SessionIndex + 1));
|
|
||||||
|
|
||||||
Session.Session.SessionSettings.Get(SETTING_MAPNAME, SessionName);
|
|
||||||
SessionNameText->SetText(FText::FromString(SessionName));
|
|
||||||
|
|
||||||
int MaxPlayerCount = Session.Session.SessionSettings.NumPublicConnections;
|
|
||||||
int CurPlayerCount = MaxPlayerCount - Session.Session.NumOpenPublicConnections;
|
|
||||||
|
|
||||||
PlayersCountText->SetText(FText::AsNumber(CurPlayerCount));
|
|
||||||
PingText->SetText(FText::AsNumber(Session.PingInMs));
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "Interfaces/OnlineSessionInterface.h"
|
|
||||||
#include "Blueprint/UserWidget.h"
|
|
||||||
#include "MySessionListEntryWidget.generated.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class TURNBASEDTUTORIAL_API UMySessionListEntryWidget : public UUserWidget
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
|
||||||
class UTextBlock* IndexText;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
|
||||||
class UTextBlock* SessionNameText;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
|
||||||
class UTextBlock* PlayersCountText;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(BindWidget))
|
|
||||||
class UTextBlock* PingText;
|
|
||||||
|
|
||||||
void Update(int SessionIndex, const FOnlineSessionSearchResult& Session);
|
|
||||||
|
|
||||||
int SessionId;
|
|
||||||
FString SessionName;
|
|
||||||
};
|
|
@ -1,81 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "MySessionListWidget.h"
|
|
||||||
|
|
||||||
#include "MyGameInstanceSubsystem.h"
|
|
||||||
#include "Components/VerticalBox.h"
|
|
||||||
#include "MySessionListEntryWidget.h"
|
|
||||||
#include "Components/Button.h"
|
|
||||||
#include "Kismet/GameplayStatics.h"
|
|
||||||
|
|
||||||
void UMySessionListWidget::NativeConstruct()
|
|
||||||
{
|
|
||||||
Super::NativeConstruct();
|
|
||||||
|
|
||||||
RefreshListButton->OnClicked.AddDynamic(this, &ThisClass::OnRefreshListButtonClicked);
|
|
||||||
ConnectToSelectedSessionButton->OnClicked.AddDynamic(this, &ThisClass::ConnectToFirstSession);
|
|
||||||
|
|
||||||
const auto MyGameInstanceSubsystem = GetMyGameSubsystem();
|
|
||||||
MyGameInstanceSubsystem->OnFindSessionsCompleteEvent.AddUObject(this, &ThisClass::RefreshList);
|
|
||||||
MyGameInstanceSubsystem->OnJoinSessionCompleteEvent.AddUObject(this, &ThisClass::OnJoinSessionSuccess);
|
|
||||||
|
|
||||||
// Initiate search
|
|
||||||
MyGameInstanceSubsystem->FindSessions(10, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMySessionListWidget::RefreshList(const TArray<FOnlineSessionSearchResult>& SessionResults,
|
|
||||||
bool bSuccessful)
|
|
||||||
{
|
|
||||||
if (!bSuccessful)
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Error, TEXT("Find sessions FAILED!!!!"));
|
|
||||||
// TODO: Mark find sessions error
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SessionListBox->ClearChildren();
|
|
||||||
for (const auto &Session: SessionResults)
|
|
||||||
{
|
|
||||||
auto *ItemWidget = CreateWidget<UMySessionListEntryWidget>(this, EntryClass);
|
|
||||||
ItemWidget->Update(SessionListBox->GetChildrenCount(), Session);
|
|
||||||
SessionListBox->AddChild(ItemWidget);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMySessionListWidget::OnRefreshListButtonClicked()
|
|
||||||
{
|
|
||||||
// TODO: Show that we started searching...
|
|
||||||
// Initiate search
|
|
||||||
SessionListBox->ClearChildren();
|
|
||||||
GetMyGameSubsystem()->FindSessions(10, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UMySessionListWidget::ConnectToFirstSession()
|
|
||||||
{
|
|
||||||
GetMyGameSubsystem()->JoinSession(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void UMySessionListWidget::OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result)
|
|
||||||
{
|
|
||||||
if (Result != EOnJoinSessionCompleteResult::Success)
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Error, TEXT("Failed to connect to session!!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!GetMyGameSubsystem()->TryConnectToCurrentSession())
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Error, TEXT("Failed to travel client to session!!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
UE_LOG(LogTemp, Display, TEXT("Connected and travelled to session!!!"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
UMyGameInstanceSubsystem* UMySessionListWidget::GetMyGameSubsystem() const
|
|
||||||
{
|
|
||||||
const UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(GetWorld());
|
|
||||||
UMyGameInstanceSubsystem* GameInstanceSubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();
|
|
||||||
return GameInstanceSubsystem;
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "MyGameInstanceSubsystem.h"
|
|
||||||
|
|
||||||
#include "Blueprint/UserWidget.h"
|
|
||||||
#include "MySessionListWidget.generated.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
UCLASS()
|
|
||||||
class TURNBASEDTUTORIAL_API UMySessionListWidget : public UUserWidget
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void NativeConstruct() override;
|
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
|
||||||
class UButton* ConnectToSelectedSessionButton;
|
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
|
||||||
class UButton* GoBackToMainMenuButton;
|
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
|
||||||
class UButton* RefreshListButton;
|
|
||||||
|
|
||||||
UPROPERTY(meta = (BindWidget))
|
|
||||||
class UVerticalBox* SessionListBox;
|
|
||||||
|
|
||||||
UPROPERTY(EditDefaultsOnly, Category="Session Info Class")
|
|
||||||
TSubclassOf<class UMySessionListEntryWidget> EntryClass;
|
|
||||||
|
|
||||||
void RefreshList(const TArray<FOnlineSessionSearchResult>& SessionResults, bool bSuccessful);
|
|
||||||
|
|
||||||
void OnJoinSessionSuccess(EOnJoinSessionCompleteResult::Type Result);
|
|
||||||
|
|
||||||
private:
|
|
||||||
UMyGameInstanceSubsystem* GetMyGameSubsystem() const;
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void OnRefreshListButtonClicked();
|
|
||||||
|
|
||||||
UFUNCTION()
|
|
||||||
void ConnectToFirstSession();
|
|
||||||
};
|
|
@ -0,0 +1,399 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#include "SessionsGameInstanceSubsystem.h"
|
||||||
|
|
||||||
|
#include "BattleMode/BattlePlayerController.h"
|
||||||
|
#include "OnlineSubsystemUtils.h"
|
||||||
|
#include "GameFramework/GameModeBase.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
|
USessionsGameInstanceSubsystem::USessionsGameInstanceSubsystem()
|
||||||
|
: bIsHost(false),
|
||||||
|
CreateSessionCompleteDelegate(
|
||||||
|
FOnCreateSessionCompleteDelegate::CreateUObject(
|
||||||
|
this, &ThisClass::OnCreateSessionCompleted)),
|
||||||
|
UpdateSessionCompleteDelegate(
|
||||||
|
FOnUpdateSessionCompleteDelegate::CreateUObject(
|
||||||
|
this, &ThisClass::OnUpdateSessionCompleted)),
|
||||||
|
StartSessionCompleteDelegate(
|
||||||
|
FOnStartSessionCompleteDelegate::CreateUObject(
|
||||||
|
this, &ThisClass::OnStartSessionCompleted)),
|
||||||
|
EndSessionCompleteDelegate(
|
||||||
|
FOnEndSessionCompleteDelegate::CreateUObject(
|
||||||
|
this, &ThisClass::OnEndSessionCompleted)),
|
||||||
|
DestroySessionCompleteDelegate(
|
||||||
|
FOnDestroySessionCompleteDelegate::CreateUObject(
|
||||||
|
this, &ThisClass::OnDestroySessionCompleted)),
|
||||||
|
FindSessionsCompleteDelegate(
|
||||||
|
FOnFindSessionsCompleteDelegate::CreateUObject(
|
||||||
|
this, &ThisClass::OnFindSessionsCompleted)),
|
||||||
|
JoinSessionCompleteDelegate(
|
||||||
|
FOnJoinSessionCompleteDelegate::CreateUObject(
|
||||||
|
this, &ThisClass::OnJoinSessionCompleted)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::CreateSession(FString SessionName,
|
||||||
|
int32 NumPublicConnections,
|
||||||
|
bool bIsLANMatch) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnCreateSessionCompleteEvent.Broadcast(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastSessionSettings = MakeShareable(new FOnlineSessionSettings());
|
||||||
|
LastSessionSettings->NumPrivateConnections = 0;
|
||||||
|
LastSessionSettings->NumPublicConnections = NumPublicConnections;
|
||||||
|
LastSessionSettings->bAllowInvites = true;
|
||||||
|
LastSessionSettings->bAllowJoinInProgress = true;
|
||||||
|
LastSessionSettings->bAllowJoinViaPresence = true;
|
||||||
|
LastSessionSettings->bAllowJoinViaPresenceFriendsOnly = true;
|
||||||
|
LastSessionSettings->bUsesPresence = true;
|
||||||
|
LastSessionSettings->bIsLANMatch = bIsLANMatch;
|
||||||
|
LastSessionSettings->bShouldAdvertise = true;
|
||||||
|
|
||||||
|
LastSessionSettings->Set(SETTING_MAPNAME, SessionName,
|
||||||
|
EOnlineDataAdvertisementType::ViaOnlineService);
|
||||||
|
|
||||||
|
CreateSessionCompleteDelegateHandle = SessionInterface->
|
||||||
|
AddOnCreateSessionCompleteDelegate_Handle(
|
||||||
|
CreateSessionCompleteDelegate);
|
||||||
|
|
||||||
|
const ULocalPlayer *localPlayer = GetWorld()->
|
||||||
|
GetFirstLocalPlayerFromController();
|
||||||
|
if (!SessionInterface->CreateSession(
|
||||||
|
*localPlayer->GetPreferredUniqueNetId(), NAME_GameSession,
|
||||||
|
*LastSessionSettings)) {
|
||||||
|
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(
|
||||||
|
CreateSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnCreateSessionCompleteEvent.Broadcast(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::OnCreateSessionCompleted(
|
||||||
|
FName SessionName,
|
||||||
|
bool bSuccessful) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (SessionInterface.IsValid()) {
|
||||||
|
SessionInterface->ClearOnCreateSessionCompleteDelegate_Handle(
|
||||||
|
CreateSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
bIsHost = true;
|
||||||
|
|
||||||
|
OnCreateSessionCompleteEvent.Broadcast(bSuccessful);
|
||||||
|
}
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::UpdateSession() {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnCreateSessionCompleteEvent.Broadcast(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TSharedPtr<FOnlineSessionSettings> UpdatedSessionSettings =
|
||||||
|
MakeShareable(
|
||||||
|
new FOnlineSessionSettings(*LastSessionSettings));
|
||||||
|
|
||||||
|
// Here we can insert any changes we want
|
||||||
|
UpdatedSessionSettings->Set(SETTING_MAPNAME, FString("Updated Level Name"),
|
||||||
|
EOnlineDataAdvertisementType::ViaOnlineService);
|
||||||
|
|
||||||
|
UpdateSessionCompleteDelegateHandle =
|
||||||
|
SessionInterface->AddOnUpdateSessionCompleteDelegate_Handle(
|
||||||
|
UpdateSessionCompleteDelegate);
|
||||||
|
|
||||||
|
if (!SessionInterface->UpdateSession(NAME_GameSession,
|
||||||
|
*UpdatedSessionSettings)) {
|
||||||
|
SessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(
|
||||||
|
UpdateSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnUpdateSessionCompleteEvent.Broadcast(false);
|
||||||
|
} else {
|
||||||
|
LastSessionSettings = UpdatedSessionSettings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::OnUpdateSessionCompleted(
|
||||||
|
FName SessionName,
|
||||||
|
bool bSuccessful) {
|
||||||
|
const IOnlineSessionPtr sessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (sessionInterface.IsValid()) {
|
||||||
|
sessionInterface->ClearOnUpdateSessionCompleteDelegate_Handle(
|
||||||
|
UpdateSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnUpdateSessionCompleteEvent.Broadcast(bSuccessful);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::StartSession() {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnCreateSessionCompleteEvent.Broadcast(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StartSessionCompleteDelegateHandle = SessionInterface->
|
||||||
|
AddOnStartSessionCompleteDelegate_Handle(
|
||||||
|
StartSessionCompleteDelegate);
|
||||||
|
|
||||||
|
if (!SessionInterface->StartSession(NAME_GameSession)) {
|
||||||
|
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(
|
||||||
|
StartSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnStartSessionCompleteEvent.Broadcast(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::OnStartSessionCompleted(
|
||||||
|
FName SessionName,
|
||||||
|
bool bSuccessful) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (SessionInterface.IsValid()) {
|
||||||
|
SessionInterface->ClearOnStartSessionCompleteDelegate_Handle(
|
||||||
|
StartSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
OnStartSessionCompleteEvent.Broadcast(bSuccessful);
|
||||||
|
|
||||||
|
// TODO: Move this from gameinstance subsystem. This should not be here.
|
||||||
|
UGameplayStatics::OpenLevel(GetWorld(), "BattleFieldMap", true, "listen");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::EndSession() {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnCreateSessionCompleteEvent.Broadcast(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EndSessionCompleteDelegateHandle = SessionInterface->
|
||||||
|
AddOnEndSessionCompleteDelegate_Handle(
|
||||||
|
EndSessionCompleteDelegate);
|
||||||
|
|
||||||
|
if (!SessionInterface->EndSession(NAME_GameSession)) {
|
||||||
|
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(
|
||||||
|
EndSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnEndSessionCompleteEvent.Broadcast(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::OnEndSessionCompleted(
|
||||||
|
FName SessionName,
|
||||||
|
bool bSuccessful) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (SessionInterface.IsValid()) {
|
||||||
|
SessionInterface->ClearOnEndSessionCompleteDelegate_Handle(
|
||||||
|
EndSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnEndSessionCompleteEvent.Broadcast(bSuccessful);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::DestroySession() {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnDestroySessionCompleteEvent.Broadcast(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroySessionCompleteDelegateHandle = SessionInterface->
|
||||||
|
AddOnDestroySessionCompleteDelegate_Handle(
|
||||||
|
DestroySessionCompleteDelegate);
|
||||||
|
|
||||||
|
if (!SessionInterface->DestroySession(NAME_GameSession)) {
|
||||||
|
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(
|
||||||
|
EndSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnDestroySessionCompleteEvent.Broadcast(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::OnDestroySessionCompleted(
|
||||||
|
FName SessionName,
|
||||||
|
bool bSuccessful) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (SessionInterface.IsValid()) {
|
||||||
|
SessionInterface->ClearOnDestroySessionCompleteDelegate_Handle(
|
||||||
|
DestroySessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnDestroySessionCompleteEvent.Broadcast(bSuccessful);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::FindSessions(int32 MaxSearchResults,
|
||||||
|
bool bIsLANQuery) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnFindSessionsCompleteEvent.Broadcast(
|
||||||
|
TArray<FOnlineSessionSearchResult>(), false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FindSessionsCompleteDelegateHandle = SessionInterface->
|
||||||
|
AddOnFindSessionsCompleteDelegate_Handle(
|
||||||
|
FindSessionsCompleteDelegate);
|
||||||
|
|
||||||
|
LastSessionSearch = MakeShareable(new FOnlineSessionSearch());
|
||||||
|
LastSessionSearch->MaxSearchResults = MaxSearchResults;
|
||||||
|
LastSessionSearch->bIsLanQuery = bIsLANQuery;
|
||||||
|
|
||||||
|
// Disable dedicated server search (maybe enable later, when dedicated server is implemented)
|
||||||
|
// LastSessionSearch->QuerySettings.Set(SEARCH_PRESENCE, true, EOnlineComparisonOp::Equals);
|
||||||
|
|
||||||
|
const ULocalPlayer *LocalPlayer = GetWorld()->
|
||||||
|
GetFirstLocalPlayerFromController();
|
||||||
|
if (!SessionInterface->FindSessions(*LocalPlayer->GetPreferredUniqueNetId(),
|
||||||
|
LastSessionSearch.ToSharedRef())) {
|
||||||
|
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(
|
||||||
|
FindSessionsCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnFindSessionsCompleteEvent.Broadcast(
|
||||||
|
TArray<FOnlineSessionSearchResult>(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::OnFindSessionsCompleted(bool bSuccessful) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (SessionInterface.IsValid()) {
|
||||||
|
SessionInterface->ClearOnFindSessionsCompleteDelegate_Handle(
|
||||||
|
FindSessionsCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LastSessionSearch->SearchResults.Num() <= 0) {
|
||||||
|
OnFindSessionsCompleteEvent.Broadcast(
|
||||||
|
TArray<FOnlineSessionSearchResult>(), bSuccessful);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnFindSessionsCompleteEvent.Broadcast(LastSessionSearch->SearchResults,
|
||||||
|
bSuccessful);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::JoinSession(
|
||||||
|
const FOnlineSessionSearchResult &SessionSearchResult) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnJoinSessionCompleteEvent.Broadcast(
|
||||||
|
EOnJoinSessionCompleteResult::UnknownError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoinSessionCompleteDelegateHandle = SessionInterface->
|
||||||
|
AddOnJoinSessionCompleteDelegate_Handle(
|
||||||
|
JoinSessionCompleteDelegate);
|
||||||
|
|
||||||
|
const ULocalPlayer *LocalPlayer = GetWorld()->
|
||||||
|
GetFirstLocalPlayerFromController();
|
||||||
|
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),
|
||||||
|
NAME_GameSession, SessionSearchResult)) {
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(
|
||||||
|
JoinSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnJoinSessionCompleteEvent.Broadcast(
|
||||||
|
EOnJoinSessionCompleteResult::UnknownError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::JoinSession(const int32 Index) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
OnJoinSessionCompleteEvent.Broadcast(
|
||||||
|
EOnJoinSessionCompleteResult::UnknownError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!LastSessionSearch.IsValid() || Index >= LastSessionSearch->
|
||||||
|
SearchResults.Num()) {
|
||||||
|
OnJoinSessionCompleteEvent.Broadcast(
|
||||||
|
EOnJoinSessionCompleteResult::UnknownError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JoinSessionCompleteDelegateHandle = SessionInterface->
|
||||||
|
AddOnJoinSessionCompleteDelegate_Handle(
|
||||||
|
JoinSessionCompleteDelegate);
|
||||||
|
|
||||||
|
const ULocalPlayer *LocalPlayer = GetWorld()->
|
||||||
|
GetFirstLocalPlayerFromController();
|
||||||
|
if (!SessionInterface->JoinSession(*LocalPlayer->GetPreferredUniqueNetId(),
|
||||||
|
NAME_GameSession,
|
||||||
|
LastSessionSearch->SearchResults[
|
||||||
|
Index])) {
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(
|
||||||
|
JoinSessionCompleteDelegateHandle);
|
||||||
|
|
||||||
|
OnJoinSessionCompleteEvent.Broadcast(
|
||||||
|
EOnJoinSessionCompleteResult::UnknownError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::OnJoinSessionCompleted(
|
||||||
|
FName SessionName,
|
||||||
|
EOnJoinSessionCompleteResult::Type Result) {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (SessionInterface.IsValid()) {
|
||||||
|
SessionInterface->ClearOnJoinSessionCompleteDelegate_Handle(
|
||||||
|
JoinSessionCompleteDelegateHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnJoinSessionCompleteEvent.Broadcast(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool USessionsGameInstanceSubsystem::TryConnectToCurrentSession() const {
|
||||||
|
const IOnlineSessionPtr SessionInterface = Online::GetSessionInterface(
|
||||||
|
GetWorld());
|
||||||
|
if (!SessionInterface.IsValid()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString ConnectString;
|
||||||
|
if (!SessionInterface->GetResolvedConnectString(
|
||||||
|
NAME_GameSession, ConnectString)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
APlayerController *PlayerController = GetWorld()->
|
||||||
|
GetFirstPlayerController();
|
||||||
|
PlayerController->ClientTravel(ConnectString, TRAVEL_Absolute);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USessionsGameInstanceSubsystem::QuitCurrentSession() {
|
||||||
|
if (bIsHost) {
|
||||||
|
UGameplayStatics::GetGameMode(GetWorld())->ReturnToMainMenuHost();
|
||||||
|
} else {
|
||||||
|
APlayerController *LocalController = GEngine->
|
||||||
|
GetFirstLocalPlayerController(GetWorld());
|
||||||
|
LocalController->ClientReturnToMainMenuWithTextReason(
|
||||||
|
FText::FromString("Session ended"));
|
||||||
|
}
|
||||||
|
bIsHost = false;
|
||||||
|
DestroySession();
|
||||||
|
}
|
@ -0,0 +1,116 @@
|
|||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "OnlineSessionSettings.h"
|
||||||
|
#include "Interfaces/OnlineSessionInterface.h"
|
||||||
|
#include "Subsystems/GameInstanceSubsystem.h"
|
||||||
|
#include "SessionsGameInstanceSubsystem.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnCreateSessionComplete, bool,
|
||||||
|
bSuccessful);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnUpdateSessionComplete, bool,
|
||||||
|
bSuccessful);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnStartSessionCompete, bool,
|
||||||
|
bSuccessful);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnEndSessionComplete, bool,
|
||||||
|
bSuccessful);
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyOnDestroySessionComplete, bool,
|
||||||
|
bSuccessful);
|
||||||
|
|
||||||
|
DECLARE_MULTICAST_DELEGATE_TwoParams(FMyOnFindSessionsComplete,
|
||||||
|
const TArray<FOnlineSessionSearchResult>&
|
||||||
|
SessionResults, bool bSuccessful);
|
||||||
|
|
||||||
|
DECLARE_MULTICAST_DELEGATE_OneParam(FMyOnJoinSessionCompele,
|
||||||
|
EOnJoinSessionCompleteResult::Type Result);
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class TURNBASEDTUTORIAL_API USessionsGameInstanceSubsystem
|
||||||
|
: public UGameInstanceSubsystem {
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
USessionsGameInstanceSubsystem();
|
||||||
|
|
||||||
|
void CreateSession(FString SessionName,
|
||||||
|
int32 NumPublicConnections,
|
||||||
|
bool bIsLANMatch);
|
||||||
|
|
||||||
|
void UpdateSession();
|
||||||
|
|
||||||
|
void StartSession();
|
||||||
|
|
||||||
|
void EndSession();
|
||||||
|
|
||||||
|
void DestroySession();
|
||||||
|
|
||||||
|
void FindSessions(int32 MaxSearchResults, bool bIsLANQuery);
|
||||||
|
|
||||||
|
void JoinSession(const FOnlineSessionSearchResult &SessionSearchResult);
|
||||||
|
|
||||||
|
void JoinSession(const int32 Index);
|
||||||
|
|
||||||
|
bool TryConnectToCurrentSession() const;
|
||||||
|
|
||||||
|
void QuitCurrentSession();
|
||||||
|
|
||||||
|
void UpdateSessionName(FString NewSessionName);
|
||||||
|
|
||||||
|
FMyOnCreateSessionComplete OnCreateSessionCompleteEvent;
|
||||||
|
FMyOnUpdateSessionComplete OnUpdateSessionCompleteEvent;
|
||||||
|
FMyOnStartSessionCompete OnStartSessionCompleteEvent;
|
||||||
|
FMyOnEndSessionComplete OnEndSessionCompleteEvent;
|
||||||
|
FMyOnDestroySessionComplete OnDestroySessionCompleteEvent;
|
||||||
|
FMyOnFindSessionsComplete OnFindSessionsCompleteEvent;
|
||||||
|
FMyOnJoinSessionCompele OnJoinSessionCompleteEvent;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void OnCreateSessionCompleted(FName SessionName, bool bSuccessful);
|
||||||
|
|
||||||
|
void OnUpdateSessionCompleted(FName SessionName, bool bSuccessful);
|
||||||
|
|
||||||
|
void OnStartSessionCompleted(FName SessionName, bool bSuccessful);
|
||||||
|
|
||||||
|
void OnEndSessionCompleted(FName SessionName, bool bSuccessful);
|
||||||
|
|
||||||
|
void OnDestroySessionCompleted(FName SessionName, bool bSuccessful);
|
||||||
|
|
||||||
|
void OnFindSessionsCompleted(bool bSuccessful);
|
||||||
|
|
||||||
|
void OnJoinSessionCompleted(FName SessionName,
|
||||||
|
EOnJoinSessionCompleteResult::Type Result);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool bIsHost;
|
||||||
|
|
||||||
|
FOnCreateSessionCompleteDelegate CreateSessionCompleteDelegate;
|
||||||
|
FDelegateHandle CreateSessionCompleteDelegateHandle;
|
||||||
|
TSharedPtr<FOnlineSessionSettings> LastSessionSettings;
|
||||||
|
|
||||||
|
FOnUpdateSessionCompleteDelegate UpdateSessionCompleteDelegate;
|
||||||
|
FDelegateHandle UpdateSessionCompleteDelegateHandle;
|
||||||
|
|
||||||
|
FOnStartSessionCompleteDelegate StartSessionCompleteDelegate;
|
||||||
|
FDelegateHandle StartSessionCompleteDelegateHandle;
|
||||||
|
|
||||||
|
FOnEndSessionCompleteDelegate EndSessionCompleteDelegate;
|
||||||
|
FDelegateHandle EndSessionCompleteDelegateHandle;
|
||||||
|
|
||||||
|
FOnDestroySessionCompleteDelegate DestroySessionCompleteDelegate;
|
||||||
|
FDelegateHandle DestroySessionCompleteDelegateHandle;
|
||||||
|
|
||||||
|
FOnFindSessionsCompleteDelegate FindSessionsCompleteDelegate;
|
||||||
|
FDelegateHandle FindSessionsCompleteDelegateHandle;
|
||||||
|
TSharedPtr<FOnlineSessionSearch> LastSessionSearch;
|
||||||
|
|
||||||
|
FOnJoinSessionCompleteDelegate JoinSessionCompleteDelegate;
|
||||||
|
FDelegateHandle JoinSessionCompleteDelegateHandle;
|
||||||
|
};
|
Loading…
Reference in new issue