メインコンテンツまでスキップ

Unreal Engine Module - Quick Match with DS - Post match menu

Last updated on January 13, 2024
AGS Starter

This tutorial isn't yet applicable for the AccelByte Gaming Service (AGS) Starter tier. It requires the Armada, a dynamic game server manager feature, which isn't currently supported on AGS Starter.

About the Match Lobby UI

In the Byte Wars project, the Match Lobby is a widget to display players information who have successfully connected to the game server, whether it is a dedicated server (DS) or a listen server. We have set up this widget with the necessary functionalities, so in this section, you will only learn how this widget is constructed. This widget is defined in the following files.

  • Header file can be found in /Source/AccelByteWars/Core/UI/MainMenu/MatchLobby/MatchLobbyWidget.h.
  • Cpp file can be found in /Source/AccelByteWars/Core/UI/MainMenu/MatchLobby/MatchLobbyWidget.cpp.
  • Blueprint widget can be found in /Content/ByteWars/UI/MainMenu/MatchLobby/W_MatchLobby.uasset.

If you open the Match Lobby widget Blueprint file, you will see how the widget is constructed.

Preview of Match Lobby widget

As you can see from the preview above, this widget has two main buttons. The first button is to start the game and will bring the players to the gameplay level. The second one is to quit the game server. You can find the declarations for those buttons in the header file.

private:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Start;

UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Quit;

The functions to start and quit are defined in the following functions. Notice that it fires a delegate namely OnQuitLobbyDelegate that you will use to call leave session later.

void UMatchLobbyWidget::StartMatch() 
{
if (AAccelByteWarsPlayerController* PC = Cast<AAccelByteWarsPlayerController>(GetOwningPlayer()))
{
PC->TriggerLobbyStart();
}
}

void UMatchLobbyWidget::LeaveMatch()
{
if (OnQuitLobbyDelegate.IsBound())
{
OnQuitLobbyDelegate.Broadcast(GetOwningPlayer());
}

UGameplayStatics::OpenLevel(GetWorld(), TEXT("MainMenu"));
}

To generate the players information in the Match Lobby, it uses the following function.

void UMatchLobbyWidget::GenerateMultiplayerTeamEntries()
{
// Generate team entries only on game clients.
// Also, don't attempt to generate entries when the Listen Server is tearing down.
ENetMode NetMode = GetOwningPlayer()->GetNetMode();
if ((NetMode != ENetMode::NM_Client && NetMode != ENetMode::NM_ListenServer) || GetWorld()->bIsTearingDown)
{
return;
}

ResetTeamEntries();

// Spawn team and player entry widgets.
int32 PlayerIndex = 0;
for (const FGameplayTeamData& Team : GameState->Teams)
{
if (Team.TeamMembers.IsEmpty()) continue;

const TWeakObjectPtr<UTeamEntryWidget> TeamEntry = MakeWeakObjectPtr<UTeamEntryWidget>(CreateWidget<UTeamEntryWidget>(this, TeamEntryWidget.Get()));
Panel_TeamList->AddChild(TeamEntry.Get());

const FLinearColor TeamColor = GameInstance->GetTeamColor(Team.TeamId);
TeamEntry->SetTeamEntryColor(TeamColor);

// Spawn team entry widget.
for (const FGameplayPlayerData& Member : Team.TeamMembers)
{
PlayerIndex++;
const FString PlayerName = Member.PlayerName.IsEmpty() ? FString::Printf(TEXT("Player %d"), PlayerIndex) : Member.PlayerName;

// Spawn player entry and set the default username.
const TWeakObjectPtr<UPlayerEntryWidget> PlayerEntry = MakeWeakObjectPtr<UPlayerEntryWidget>(CreateWidget<UPlayerEntryWidget>(this, PlayerEntryWidget.Get()));
TeamEntry->AddPlayerEntry(PlayerEntry.Get());
PlayerEntry->SetUsername(FText::FromString(PlayerName));
PlayerEntry->SetAvatar(Member.AvatarURL);
PlayerEntry->SetAvatarTint(Member.AvatarURL.IsEmpty() ? TeamColor : FLinearColor::White);
PlayerEntry->SetTextColor(TeamColor);
}
}
}

From the code above, you can tell that it creates a widget of type TeamEntryWidget and PlayerEntryWidget to display the player information entries. Let's take a look at how those widgets are constructed.

Team Entry UI

The Match Lobby not only shows one team but can be multiple teams. Hence this Team Entry widget is used to group the player information entries based on their teams. This widget is defined in the following files.

  • Header file can be found in /Source/AccelByteWars/Core/UI/Components/MultiplayerEntries/TeamEntryWidget.h.
  • Cpp file can be found in /Source/AccelByteWars/Core/UI/Components/MultiplayerEntries/TeamEntryWidget.cpp.
  • Blueprint widget can be found in /Content/ByteWars/UI/Components/MultiplayerEntries/W_TeamEntry.uasset.

Here is the preview of the widget.

Preview of Team Entry widget

Player Entry UI

This widget is used to show player information, such as the player's display name and avatar. This widget is spawned onto the Team Entry widget to group the players based on their team. This widget is defined in the following files.

  • Header file can be found in /Source/AccelByteWars/Core/UI/Components/MultiplayerEntries/PlayerEntryWidget.h.
  • Cpp file can be found in /Source/AccelByteWars/Core/UI/Components/MultiplayerEntries/PlayerEntryWidget.cpp.
  • Blueprint widget can be found in /Content/ByteWars/UI/Components/MultiplayerEntries/W_PlayerEntry.uasset.

Here is the preview of the widget.

Preview of Player Entry widget

About the Pause UI

In the Byte Wars project, the Pause UI is a widget to be displayed when the player pauses the game. This widget displays buttons to do actions like resume, restart, and quit. We have set up this widget with the necessary functionalities, so in this section, you will only learn how this widget is constructed. This widget is defined in the following files.

  • Header file can be found in /Source/AccelByteWars/Core/UI/InGameMenu/Pause/PauseWidget.h.
  • Cpp file can be found in /Source/AccelByteWars/Core/UI/InGameMenu/Pause/PauseWidget.cpp.
  • Blueprint widget can be found in /Content/ByteWars/UI/InGameMenu/Pause/W_Pause.uasset.

Here is the preview of the Game Over widget.

Preview of Pause widget

You can find the declarations of the buttons in the header file.

private:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Resume;

UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Restart;

UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Quit;

The functions to do those actions are defined in the following functions. Notice that it fires a delegate namely OnQuitGameDelegate that you will use to call leave session later.

void UPauseWidget::ResumeGame()
{
DeactivateWidget();
}

void UPauseWidget::RestartGame()
{
if (const AAccelByteWarsGameMode* GameMode = Cast<AAccelByteWarsGameMode>(GetWorld()->GetAuthGameMode()))
{
GameMode->DelayedServerTravel("/Game/ByteWars/Maps/GalaxyWorld/GalaxyWorld");
}
}

void UPauseWidget::QuitGame()
{
if (OnQuitGameDelegate.IsBound())
{
OnQuitGameDelegate.Broadcast(GetOwningPlayer());
}

OnExitLevel();

UGameplayStatics::OpenLevel(GetWorld(), TEXT("MainMenu"));
}

About the Game Over UI

In the Byte Wars project, the Game Over UI is a widget to be displayed when the game is over. This widget displays information such as who won the game and buttons to play the game again or to quit the game. We have set up this widget with the necessary functionalities, so in this section, you will only learn how this widget is constructed. This widget is defined in the following files.

  • Header file can be found in /Source/AccelByteWars/Core/UI/InGameMenu/GameOver/GameOverWidget.h.
  • Cpp file can be found in /Source/AccelByteWars/Core/UI/InGameMenu/GameOver/GameOverWidget.cpp.
  • Blueprint widget can be found in /Content/ByteWars/UI/InGameMenu/GameOver/W_GameOver.uasset.

Here is the preview of the Game Over widget.

Preview of Game Over widget

You can find the declarations of the buttons in the header file.

private:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_PlayAgain;

UPROPERTY(BlueprintReadOnly, meta = (BindWidget, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Quit;

The functions to replay and quit are defined in the following functions. Notice that it fires a delegate namely OnQuitGameDelegate that you will use to call leave session later.

void UGameOverWidget::PlayGameAgain()
{
if (const AAccelByteWarsGameMode* GameMode = Cast<AAccelByteWarsGameMode>(GetWorld()->GetAuthGameMode()))
{
GameMode->DelayedServerTravel("/Game/ByteWars/Maps/GalaxyWorld/GalaxyWorld");
}
}

void UGameOverWidget::QuitGame()
{
if (OnQuitGameDelegate.IsBound())
{
OnQuitGameDelegate.Broadcast(GetOwningPlayer());
}

OnExitLevel();
UGameplayStatics::OpenLevel(GetWorld(), TEXT("MainMenu"));
}

Resources