Skip to main content

Add recent players menu - Recent players - (Unreal Engine module)

Last updated on October 23, 2024

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
  • 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
  • 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

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:

Recent players widget Unreal Byte Wars recent players

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:

Game session player list widget Unreal Byte Wars recent players

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:

Player entry widget Unreal Byte Wars recent players

Ready the UI

In this section, you will prepare the widgets so you can follow along with the rest of the module.

  1. 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;
  2. Open the RecentPlayersWidget_Starter class CPP file. Then, define the InitRecentPlayersList(). 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()
    {
    // ...
    }
  3. 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);
    }
  4. 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)
    {
    // ...
    }
  5. 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);
    // ...
    }
  6. 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();
    }
  7. 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);
  8. Open the PlayersListWidget_Starter class CPP file. Then, define the InitGameSessionPlayersList(). 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()
    {
    // ...
    }
  9. 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);
    }
  10. 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"));
    }
    }
  11. 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();
    }
  12. 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();
    }
  13. 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 called DA_RecentPlayers. Open it and enable the Is Starter Mode Active. Then, save the data asset. This will activate the widgets so you can navigate through them when you play the game.

  14. 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