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,120 +1,121 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "MyGameState.h"
|
||||
|
||||
// #include "GameOverWidget.h"
|
||||
#include "MyPlayerState.h"
|
||||
#include "Trooper.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
auto AMyGameState::GetMyPlayerState(uint8 PlayerIndex) const {
|
||||
return Cast<AMyPlayerState>(PlayerArray[PlayerIndex]);
|
||||
}
|
||||
|
||||
AMyGameState::AMyGameState() : Super() {
|
||||
}
|
||||
|
||||
void AMyGameState::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
LivingTroopersCount.SetNum(2);
|
||||
}
|
||||
|
||||
void AMyGameState::AddTrooper_Implementation(ATrooper *Trooper) {
|
||||
if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <=
|
||||
LivingTroopersCount.Num()) {
|
||||
if (LivingTroopersCount.Num() < 2) {
|
||||
LivingTroopersCount.SetNum(2);
|
||||
}
|
||||
LivingTroopersCount[Trooper->GetPlayerIndex()]++;
|
||||
}
|
||||
Troopers.Add(Trooper);
|
||||
}
|
||||
|
||||
void AMyGameState::StartGame_Implementation() {
|
||||
// PlayerNotInTurn()->SetEnemySelection();
|
||||
PlayerInTurn()->SetEnemySelection();
|
||||
bGameStarted = true;
|
||||
PlayerInTurn()->StartTurn();
|
||||
}
|
||||
|
||||
void AMyGameState::CycleTurns_Implementation() {
|
||||
PlayerInTurn()->EndTurn();
|
||||
for (const auto Trooper : Troopers) {
|
||||
if (Trooper != nullptr) {
|
||||
Trooper->ResetActionPoints();
|
||||
}
|
||||
}
|
||||
CurrentPlayerTurn = !CurrentPlayerTurn;
|
||||
PlayerInTurn()->StartTurn();
|
||||
}
|
||||
|
||||
// void AMyGameState::CycleTurns(uint8 CurrentPlayerIndex) {
|
||||
// if (CurrentPlayerTurn == CurrentPlayerIndex) {
|
||||
// PlayerInTurn()->EndTurn();
|
||||
// for (const auto Trooper : Troopers) {
|
||||
// if (Trooper != nullptr) {
|
||||
// Trooper->ResetActionPoints();
|
||||
// }
|
||||
// }
|
||||
// CurrentPlayerTurn = !CurrentPlayerTurn;
|
||||
// PlayerInTurn()->StartTurn();
|
||||
// }
|
||||
// }
|
||||
|
||||
AMyPlayerState *AMyGameState::PlayerInTurn() const {
|
||||
return GetMyPlayerState(CurrentPlayerTurn);
|
||||
}
|
||||
|
||||
AMyPlayerState *AMyGameState::PlayerNotInTurn() const {
|
||||
return GetMyPlayerState(!CurrentPlayerTurn);
|
||||
}
|
||||
|
||||
TArray<ATrooper *> AMyGameState::GetTroopers() const {
|
||||
return Troopers;
|
||||
}
|
||||
|
||||
bool AMyGameState::IsInTurn(uint8 PlayerIndex) const {
|
||||
return PlayerIndex == CurrentPlayerTurn;
|
||||
}
|
||||
|
||||
bool AMyGameState::IsGameStarted() const {
|
||||
return bGameStarted;
|
||||
}
|
||||
|
||||
void AMyGameState::DecreaseLivingTroopers(int PlayerIndex) {
|
||||
if (bGameIsOver)
|
||||
return;
|
||||
LivingTroopersCount[PlayerIndex]--;
|
||||
if (!bIsMultiplayer && PlayerIndex == 1) {
|
||||
return;
|
||||
}
|
||||
if (LivingTroopersCount[PlayerIndex] <= 0) {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Player %d lose!"), PlayerIndex);
|
||||
bGameIsOver = true;
|
||||
GameOver(PlayerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void AMyGameState::GameOver(int PlayerIndexLose) const {
|
||||
Cast<AMyPlayerState>(PlayerArray[0])->GameOver(PlayerIndexLose);
|
||||
if (bIsMultiplayer) {
|
||||
Cast<AMyPlayerState>(PlayerArray[1])->GameOver(PlayerIndexLose);
|
||||
}
|
||||
}
|
||||
|
||||
// void AMyGameState::GameOver_Implementation(int PlayerIndexLose) {
|
||||
// UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>(
|
||||
// GetWorld(), GameOverWidgetClass);
|
||||
// CreatedWidget->AddToViewport();
|
||||
// CreatedWidget->SetWidgetText(PlayerIndexLose != );
|
||||
// }
|
||||
|
||||
|
||||
void AMyGameState::GetLifetimeReplicatedProps(
|
||||
TArray<FLifetimeProperty> &OutLifetimeProps) const {
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
DOREPLIFETIME(AMyGameState, Troopers);
|
||||
DOREPLIFETIME(AMyGameState, CurrentPlayerTurn);
|
||||
DOREPLIFETIME(AMyGameState, bGameStarted);
|
||||
}
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "BattleGameState.h"
|
||||
|
||||
// #include "GameOverWidget.h"
|
||||
#include "BattlePlayerState.h"
|
||||
#include "Trooper/Trooper.h"
|
||||
#include "Blueprint/UserWidget.h"
|
||||
#include "Net/UnrealNetwork.h"
|
||||
|
||||
auto ABattleGameState::GetMyPlayerState(uint8 PlayerIndex) const {
|
||||
return Cast<ABattlePlayerState>(PlayerArray[PlayerIndex]);
|
||||
}
|
||||
|
||||
ABattleGameState::ABattleGameState()
|
||||
: Super() {
|
||||
}
|
||||
|
||||
void ABattleGameState::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
LivingTroopersCount.SetNum(2);
|
||||
}
|
||||
|
||||
void ABattleGameState::AddTrooper_Implementation(ATrooper *Trooper) {
|
||||
if (Trooper->GetPlayerIndex() >= 0 && Trooper->GetPlayerIndex() <=
|
||||
LivingTroopersCount.Num()) {
|
||||
if (LivingTroopersCount.Num() < 2) {
|
||||
LivingTroopersCount.SetNum(2);
|
||||
}
|
||||
LivingTroopersCount[Trooper->GetPlayerIndex()]++;
|
||||
}
|
||||
Troopers.Add(Trooper);
|
||||
}
|
||||
|
||||
void ABattleGameState::StartGame_Implementation() {
|
||||
// PlayerNotInTurn()->SetEnemySelection();
|
||||
PlayerInTurn()->SetEnemySelection();
|
||||
bGameStarted = true;
|
||||
PlayerInTurn()->StartTurn();
|
||||
}
|
||||
|
||||
void ABattleGameState::CycleTurns_Implementation() {
|
||||
PlayerInTurn()->EndTurn();
|
||||
for (const auto Trooper : Troopers) {
|
||||
if (Trooper != nullptr) {
|
||||
Trooper->ResetActionPoints();
|
||||
}
|
||||
}
|
||||
CurrentPlayerTurn = !CurrentPlayerTurn;
|
||||
PlayerInTurn()->StartTurn();
|
||||
}
|
||||
|
||||
// void AMyGameState::CycleTurns(uint8 CurrentPlayerIndex) {
|
||||
// if (CurrentPlayerTurn == CurrentPlayerIndex) {
|
||||
// PlayerInTurn()->EndTurn();
|
||||
// for (const auto Trooper : Troopers) {
|
||||
// if (Trooper != nullptr) {
|
||||
// Trooper->ResetActionPoints();
|
||||
// }
|
||||
// }
|
||||
// CurrentPlayerTurn = !CurrentPlayerTurn;
|
||||
// PlayerInTurn()->StartTurn();
|
||||
// }
|
||||
// }
|
||||
|
||||
ABattlePlayerState *ABattleGameState::PlayerInTurn() const {
|
||||
return GetMyPlayerState(CurrentPlayerTurn);
|
||||
}
|
||||
|
||||
ABattlePlayerState *ABattleGameState::PlayerNotInTurn() const {
|
||||
return GetMyPlayerState(!CurrentPlayerTurn);
|
||||
}
|
||||
|
||||
TArray<ATrooper *> ABattleGameState::GetTroopers() const {
|
||||
return Troopers;
|
||||
}
|
||||
|
||||
bool ABattleGameState::IsInTurn(uint8 PlayerIndex) const {
|
||||
return PlayerIndex == CurrentPlayerTurn;
|
||||
}
|
||||
|
||||
bool ABattleGameState::IsGameStarted() const {
|
||||
return bGameStarted;
|
||||
}
|
||||
|
||||
void ABattleGameState::DecreaseLivingTroopers(int PlayerIndex) {
|
||||
if (bGameIsOver)
|
||||
return;
|
||||
LivingTroopersCount[PlayerIndex]--;
|
||||
if (!bIsMultiplayer && PlayerIndex == 1) {
|
||||
return;
|
||||
}
|
||||
if (LivingTroopersCount[PlayerIndex] <= 0) {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Player %d lose!"), PlayerIndex);
|
||||
bGameIsOver = true;
|
||||
GameOver(PlayerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void ABattleGameState::GameOver(int PlayerIndexLose) const {
|
||||
Cast<ABattlePlayerState>(PlayerArray[0])->GameOver(PlayerIndexLose);
|
||||
if (bIsMultiplayer) {
|
||||
Cast<ABattlePlayerState>(PlayerArray[1])->GameOver(PlayerIndexLose);
|
||||
}
|
||||
}
|
||||
|
||||
// void AMyGameState::GameOver_Implementation(int PlayerIndexLose) {
|
||||
// UGameOverWidget *CreatedWidget = CreateWidget<UGameOverWidget>(
|
||||
// GetWorld(), GameOverWidgetClass);
|
||||
// CreatedWidget->AddToViewport();
|
||||
// CreatedWidget->SetWidgetText(PlayerIndexLose != );
|
||||
// }
|
||||
|
||||
|
||||
void ABattleGameState::GetLifetimeReplicatedProps(
|
||||
TArray<FLifetimeProperty> &OutLifetimeProps) const {
|
||||
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
|
||||
DOREPLIFETIME(ABattleGameState, Troopers);
|
||||
DOREPLIFETIME(ABattleGameState, CurrentPlayerTurn);
|
||||
DOREPLIFETIME(ABattleGameState, bGameStarted);
|
||||
}
|
@ -1,75 +1,75 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "MyPlayerState.h"
|
||||
#include "GameFramework/GameState.h"
|
||||
#include "MyGameState.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class TURNBASEDTUTORIAL_API AMyGameState : public AGameState {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AMyGameState();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
virtual void AddTrooper(ATrooper *Trooper);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void StartGame();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Server, Reliable)
|
||||
virtual void CycleTurns();
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
AMyPlayerState *PlayerInTurn() const;
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
AMyPlayerState *PlayerNotInTurn() const;
|
||||
|
||||
UFUNCTION()
|
||||
TArray<ATrooper *> GetTroopers() const;
|
||||
|
||||
UFUNCTION()
|
||||
bool IsInTurn(uint8 PlayerIndex) const;
|
||||
|
||||
UFUNCTION()
|
||||
bool IsGameStarted() const;
|
||||
|
||||
UFUNCTION()
|
||||
void DecreaseLivingTroopers(int PlayerIndex);
|
||||
|
||||
UFUNCTION()
|
||||
void GameOver(int PlayerIndexLose) const;
|
||||
|
||||
protected:
|
||||
// UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
// TSubclassOf<UUserWidget> GameOverWidgetClass;
|
||||
|
||||
UPROPERTY()
|
||||
bool bIsMultiplayer = true;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
bool bGameIsOver = false;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TArray<ATrooper *> Troopers;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TArray<int> LivingTroopersCount;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
bool bGameStarted = false;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
uint8 CurrentPlayerTurn{0};
|
||||
|
||||
auto GetMyPlayerState(uint8 PlayerIndex) const;
|
||||
};
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "BattlePlayerState.h"
|
||||
#include "GameFramework/GameState.h"
|
||||
#include "BattleGameState.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class TURNBASEDTUTORIAL_API ABattleGameState : public AGameState {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
ABattleGameState();
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
virtual void AddTrooper(ATrooper *Trooper);
|
||||
|
||||
UFUNCTION(Server, Reliable)
|
||||
void StartGame();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Server, Reliable)
|
||||
virtual void CycleTurns();
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
ABattlePlayerState *PlayerInTurn() const;
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
ABattlePlayerState *PlayerNotInTurn() const;
|
||||
|
||||
UFUNCTION()
|
||||
TArray<ATrooper *> GetTroopers() const;
|
||||
|
||||
UFUNCTION()
|
||||
bool IsInTurn(uint8 PlayerIndex) const;
|
||||
|
||||
UFUNCTION()
|
||||
bool IsGameStarted() const;
|
||||
|
||||
UFUNCTION()
|
||||
void DecreaseLivingTroopers(int PlayerIndex);
|
||||
|
||||
UFUNCTION()
|
||||
void GameOver(int PlayerIndexLose) const;
|
||||
|
||||
protected:
|
||||
// UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
// TSubclassOf<UUserWidget> GameOverWidgetClass;
|
||||
|
||||
UPROPERTY()
|
||||
bool bIsMultiplayer = true;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
bool bGameIsOver = false;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TArray<ATrooper *> Troopers;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
TArray<int> LivingTroopersCount;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
bool bGameStarted = false;
|
||||
|
||||
UPROPERTY(Replicated)
|
||||
uint8 CurrentPlayerTurn{0};
|
||||
|
||||
auto GetMyPlayerState(uint8 PlayerIndex) const;
|
||||
};
|
@ -1,35 +1,34 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "MyPawn.h"
|
||||
|
||||
|
||||
// Sets default values
|
||||
AMyPawn::AMyPawn() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
void AMyPawn::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void AMyPawn::MoveForward(float Val) {
|
||||
if (Val != 0.f)
|
||||
{
|
||||
if (Controller)
|
||||
{
|
||||
FRotator ControlSpaceRot = Controller->GetControlRotation();
|
||||
ControlSpaceRot.Pitch = 0;
|
||||
|
||||
// transform to world space and add it
|
||||
AddMovementInput( FRotationMatrix(ControlSpaceRot).GetScaledAxis( EAxis::X ), Val );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called to bind functionality to input
|
||||
void AMyPawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) {
|
||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||
}
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "BattlePawn.h"
|
||||
|
||||
|
||||
// Sets default values
|
||||
ABattlePawn::ABattlePawn() {
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Called when the game starts or when spawned
|
||||
void ABattlePawn::BeginPlay() {
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void ABattlePawn::MoveForward(float Val) {
|
||||
if (Val != 0.f) {
|
||||
if (Controller) {
|
||||
FRotator ControlSpaceRot = Controller->GetControlRotation();
|
||||
ControlSpaceRot.Pitch = 0;
|
||||
|
||||
// transform to world space and add it
|
||||
AddMovementInput(
|
||||
FRotationMatrix(ControlSpaceRot).GetScaledAxis(EAxis::X), Val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Called to bind functionality to input
|
||||
void ABattlePawn::SetupPlayerInputComponent(UInputComponent *PlayerInputComponent) {
|
||||
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||
}
|
@ -1,29 +1,27 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "GameFramework/SpectatorPawn.h"
|
||||
#include "MyPawn.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class TURNBASEDTUTORIAL_API AMyPawn : public ASpectatorPawn {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this pawn's properties
|
||||
AMyPawn();
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void MoveForward(float Val) override;
|
||||
|
||||
public:
|
||||
|
||||
// Called to bind functionality to input
|
||||
virtual void SetupPlayerInputComponent(
|
||||
class UInputComponent *PlayerInputComponent) override;
|
||||
};
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/SpectatorPawn.h"
|
||||
#include "BattlePawn.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class TURNBASEDTUTORIAL_API ABattlePawn : public ASpectatorPawn {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this pawn's properties
|
||||
ABattlePawn();
|
||||
|
||||
protected:
|
||||
// Called when the game starts or when spawned
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void MoveForward(float Val) override;
|
||||
|
||||
public:
|
||||
// Called to bind functionality to input
|
||||
virtual void SetupPlayerInputComponent(
|
||||
class UInputComponent *PlayerInputComponent) override;
|
||||
};
|
@ -1,8 +1,8 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "MyPlayerStart.h"
|
||||
|
||||
uint8 AMyPlayerStart::GetPlayerIndex() const {
|
||||
return PlayerIndex;
|
||||
}
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "BattlePlayerStart.h"
|
||||
|
||||
uint8 ABattlePlayerStart::GetPlayerIndex() const {
|
||||
return PlayerIndex;
|
||||
}
|
@ -1,23 +1,23 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/PlayerStart.h"
|
||||
#include "MyPlayerStart.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class TURNBASEDTUTORIAL_API AMyPlayerStart : public APlayerStart {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
uint8 GetPlayerIndex() const;
|
||||
|
||||
protected:
|
||||
private:
|
||||
UPROPERTY(EditAnywhere, Category="Spawn Info")
|
||||
uint8 PlayerIndex = 0;
|
||||
};
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/PlayerStart.h"
|
||||
#include "BattlePlayerStart.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS()
|
||||
class TURNBASEDTUTORIAL_API ABattlePlayerStart : public APlayerStart {
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
uint8 GetPlayerIndex() const;
|
||||
|
||||
protected:
|
||||
private:
|
||||
UPROPERTY(EditAnywhere, Category="Spawn Info")
|
||||
uint8 PlayerIndex = 0;
|
||||
};
|
@ -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