Add recent players menu - Recent players - (Unreal Engine module)
What's on the menu
In this tutorial, you will learn the widgets you will use to display the recent player list and game session player list. The widgets are available in the Resources section and are defined in the following classes:
RecentPlayersWidget_Starter
: A C++ class you will use to call functions to display the recent player list.- Header file:
/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/RecentPlayersWidget_Starter.h
- CPP file:
/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/RecentPlayersWidget_Starter.cpp
- Blueprint widget:
/Content/TutorialModules/Social/RecentPlayers/UI/W_RecentPlayers_Starter.uasset
- Header file:
PlayersListWidget_Starter
: A C++ class you will use to call functions to display the player list of a running game session.- Header file:
/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/PlayersListWidget_Starter.h
- CPP file:
/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/PlayersListWidget_Starter.cpp
- Blueprint widget:
/Content/TutorialModules/Social/RecentPlayers/UI/W_PlayersList_Starter.uasset
- Header file:
FriendWidgetEntry
: A C++ class you will use to display the recent player and game session player list entries.- Header file:
/Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FriendWidgetEntry.h
- CPP file:
/Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FriendWidgetEntry.cpp
- Blueprint widget:
/Content/TutorialModules/Social/FriendsEssentials/UI/W_FriendEntry.uasset
- Header file:
Take a look at more details on how these widgets are constructed.
Recent players widget
This widget displays the recent player list containing players who recently played a game session together. It has several states representing each state of the request status: empty, loading, error, and not empty (showing the recent players list). These states are achieved by using a custom Widget Switcher: UAccelByteWarsWidgetSwitcher
. The list itself is created by using a Tile View that takes an entry widget class and generates the entry dynamically. Below is a preview of the W_RecentPlayers_Starter
Blueprint widget:
The UI components to show the recent player list is defined in the RecentPlayersWidget_Starter
class Header file.
protected:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UAccelByteWarsWidgetSwitcher* Ws_RecentPlayers;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UTileView* Tv_RecentPlayers;
Game session player list widget
This widget displays the player list of a running game session. It has several states representing each state of the request status: empty, loading, error, and not empty (showing the recent players list). These states are achieved by using a custom Widget Switcher: UAccelByteWarsWidgetSwitcher
. The list itself is created by using a Tile View that takes an entry widget class and generates the entry dynamically. Below is a preview of the W_PlayersList_Starter
Blueprint widget:
The UI components to show the recent player list is defined in the PlayersListWidget_Starter
class Header file.
protected:
// ...
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UAccelByteWarsWidgetSwitcher* Ws_PlayersList;
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UTileView* Tv_PlayersList;
Player entry widget
You used the W_FriendEntry
widget in friend-related tutorial modules. In this module, you will reuse this widget to display individual recent players and game session player information, including display names and player statuses. Below is a preview of the widget:
Ready the UI
In this section, you will prepare the widgets so you can follow along with the rest of the module.
Open the
RecentPlayersWidget_Starter
class Header file and declare the functions and delegate below:protected:
// ...
void InitRecentPlayersList();
void OnRecentPlayerEntryClicked(UObject* Item);
// ...
FDelegateHandle OnRecentPlayersListUpdatedDelegateHandle;private:
void OnQueryRecentPlayerComplete(const FUniqueNetId& UserId, const FString& Namespace, bool bWasSuccessful, const FString& Error);
FOnQueryRecentPlayersCompleteDelegate OnQueryRecentPlayersCompletedDelegate;Open the
RecentPlayersWidget_Starter
class CPP file. Then, define theInitRecentPlayersList()
. You will use this function to get recent players and display them when the widget is displayed. For now, you can leave the function empty.void URecentPlayersWidget_Starter::InitRecentPlayersList()
{
// ...
}Next, define the
OnRecentPlayerEntryClicked()
by adding the code below. You will use this function to open the player details menu when the entry widget is clicked. On the player details menu, you can perform actions which you have implemented in other tutorial modules, such as invite as friends and invite to party.void URecentPlayersWidget_Starter::OnRecentPlayerEntryClicked(UObject* Item)
{
if (!Item)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. The recent player entry's object item is not valid."));
return;
}
UFriendData* FriendData = Cast<UFriendData>(Item);
if (!FriendData)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. The recent player entry's friend data is not valid."));
return;
}
UAccelByteWarsBaseUI* BaseUIWidget = Cast<UAccelByteWarsBaseUI>(GameInstance->GetBaseUIWidget());
if (!BaseUIWidget)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. Base UI widget is not valid."));
return;
}
UFriendDetailsWidget* DetailsWidget = Cast<UFriendDetailsWidget>(BaseUIWidget->PushWidgetToStack(EBaseUIStackType::Menu, RecentPlayerDetailsWidgetClass));
if (!DetailsWidget)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. Recent player details widget is not valid."));
return;
}
DetailsWidget->InitData(FriendData);
}Define the
OnQueryRecentPlayerComplete()
function. You will use this function to refresh the the recent player list on the widget. This function will be called every time a recent player list is queried. Later, you will query the recent players when a game session is finished. For now, you can leave the function empty.void URecentPlayersWidget_Starter::OnQueryRecentPlayerComplete(const FUniqueNetId& UserId, const FString& Namespace,
bool bWasSuccessful, const FString& Error)
{
// ...
}Next, locate the predefined
NativeOnActivated()
function. This function will be called when the widget is displayed. In this function, add the code below to initialize the UI components.void URecentPlayersWidget_Starter::NativeOnActivated()
{
Super::NativeOnActivated();
Btn_Back->OnClicked().AddUObject(this, &ThisClass::DeactivateWidget);
// Reset widgets.
Ws_RecentPlayers->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Loading);
Tv_RecentPlayers->ClearListItems();
Tv_RecentPlayers->OnItemClicked().AddUObject(this, &ThisClass::OnRecentPlayerEntryClicked);
// ...
}Then, locate the predefined
NativeOnDeactivated()
function. This function will be called when the widget is deactivated. In this function, add the code below to deinitialize the UI components.void URecentPlayersWidget_Starter::NativeOnDeactivated()
{
Btn_Back->OnClicked().Clear();
Tv_RecentPlayers->OnItemClicked().Clear();
// ...
Super::NativeOnDeactivated();
}Now, open the
PlayersListWidget_Starter
class Header file and declare the functions and delegate below:protected:
// ...
void InitGameSessionPlayersList();
void OnPlayersListEntryClicked(UObject* Item);
void OnSessionParticipantsChanged(FName SessionName, const FUniqueNetId& User, bool bJoined);Open the
PlayersListWidget_Starter
class CPP file. Then, define theInitGameSessionPlayersList()
. You will use this function to get the game session player list and display it when the widget is displayed. For now, you can leave the function empty.void UPlayersListWidget_Starter::InitGameSessionPlayersList()
{
// ...
}Next, define the
OnPlayersListEntryClicked()
by adding the code below. You will use this function to open the player details menu when the entry widget is clicked. On the player details menu, you can perform actions which you have implemented in other modules, such as invite as friends.void UPlayersListWidget_Starter::OnPlayersListEntryClicked(UObject* Item)
{
if (!Item)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. The recent player entry's object item is not valid."));
return;
}
UFriendData* FriendData = Cast<UFriendData>(Item);
if (!FriendData)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. The recent player entry's friend data is not valid."));
return;
}
UAccelByteWarsBaseUI* BaseUIWidget = Cast<UAccelByteWarsBaseUI>(GameInstance->GetBaseUIWidget());
if (!BaseUIWidget)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. Base UI widget is not valid."));
return;
}
UFriendDetailsWidget* DetailsWidget = Cast<UFriendDetailsWidget>(BaseUIWidget->PushWidgetToStack(EBaseUIStackType::InGameMenu, PlayersListDetailsWidgetClass));
if (!DetailsWidget)
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Unable to handle recent player entry on-click event. Recent player details widget is not valid."));
return;
}
DetailsWidget->InitData(FriendData);
}Define the
OnSessionParticipantsChanged()
function by adding the code below. You will use this function to refresh the the game session player list on the widget. Later, you will bind this function to be called every time game session members change.void UPlayersListWidget_Starter::OnSessionParticipantsChanged(FName SessionName, const FUniqueNetId& User, bool bJoined)
{
if(SessionName.IsEqual(NAME_GameSession))
{
if(!Tv_PlayersList->GetListItems().ContainsByPredicate([&User](UObject* Object)
{
UFriendData* PlayerData = StaticCast<UFriendData*>(Object);
if(PlayerData)
{
return User == *PlayerData->UserId.Get() ;
}
return false;
}))
{
Tv_PlayersList->ClearListItems();
InitGameSessionPlayersList();
}
}
else
{
UE_LOG_RECENTPLAYERS(Warning, TEXT("Player list not game session"));
}
}Next, locate the predefined
NativeOnActivated()
function. This function will be called when the widget is displayed. In this function, add the code below to initialize the UI components.void UPlayersListWidget_Starter::NativeOnActivated()
{
Super::NativeOnActivated();
Btn_Back->OnClicked().AddUObject(this, &ThisClass::DeactivateWidget);
// Reset widgets.
Ws_PlayersList->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Loading);
Tv_PlayersList->ClearListItems();
InitGameSessionPlayersList();
SetInputModeToUIOnly();
}Then, locate the predefined
NativeOnDeactivated()
function. This function will be called when the widget is deactivated. In this function, add the code below to deinitialize the UI components.void UPlayersListWidget_Starter::NativeOnDeactivated()
{
Super::NativeOnDeactivated();
Btn_Back->OnClicked().Clear();
}Build your project and open it in the Unreal Engine Editor. In the editor, go to
/Content/TutorialModules/Social/RecentPlayers/
. There, you will find a data asset calledDA_RecentPlayers
. Open it and enable theIs Starter Mode Active
. Then, save the data asset. This will activate the widgets so you can navigate through them when you play the game.Play the game in the editor, log in, and test the following:
To open recent player list menu, from the main menu, navigate to Social > Recent Players. You will see an empty list there.
To open game session player list menu, you need to play a match of Byte Wars. In the gameplay level, open the pause menu and navigate to Player List. You will see an empty list there.
Resources
- The files used in this tutorial section are available in the Unreal Byte Wars GitHub repository.
- AccelByteWars/Content/TutorialModules/Social/RecentPlayers/DA_RecentPlayers.uasset
- AccelByteWars/Content/TutorialModules/Social/RecentPlayers/W_RecentPlayers_Starter.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/RecentPlayersWidget_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/RecentPlayersWidget_Starter.cpp
- AccelByteWars/Content/TutorialModules/Social/RecentPlayers/UI/W_PlayersList_Starter.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/PlayersListWidget_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/RecentPlayers/UI/PlayersListWidget_Starter.cpp