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

Unreal Engine Module - Search Player - Add find friends menu

Last updated on January 13, 2024

What's on the menu

In this section, you will learn how to prepare widgets that you will use to find potential friends by their display name and send friend invitation requests. The widgets are defined in the following classes.

  • First, there is a C++ class called FindFriendsWidget_Starter. You will use this class to call some functionalities in order to find potential friends. This class is defined in the following files.

    • Header file can be found in /Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FindFriendsWidget_Starter.h.
    • CPP file can be found in /Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FindFriendsWidget_Starter.cpp.
    • Blueprint widget can be found in /Content/TutorialModules/Social/FriendsEssentials/UI/W_FindFriends_Starter.uasset.
  • Second, there is a C++ class called FriendWidgetEntry_Starter. You will use this class to display the found potential friends' information, such as their display name, avatar, and option buttons. This class is defined in the following files.

    • Header file can be found in /Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FriendWidgetEntry_Starter.h.
    • CPP file can be found in /Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FriendWidgetEntry_Starter.cpp.
    • Blueprint widget can be found in /Content/TutorialModules/Social/FriendsEssentials/UI/W_FriendEntry_Starter.uasset.

Now, let's take a look at more details on how these widgets are constructed.

Find Friend widget

Find Friend widget have several states representing each state of the request status: empty, loading, error, and not empty (showing the search result list). These states are achieved by using our custom Widget Switcher, the UAccelByteWarsWidgetSwitcher. The list itself is done by using a List View that takes an entry widget class and generate the entry dynamically. This widget also consists of a search bar. Below is the preview of the W_FindFriends_Starter Blueprint widget:

Find friend widget

The components above are declared in the FindFriendsWidget_Starter class header file.

protected:
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UEditableText* Edt_SearchBar;

UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UAccelByteWarsWidgetSwitcher* Ws_FindFriends;

UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UListView* Lv_FindFriends;

Changing the state of this widget is done by calling Ws_FindFriends->SetWidgetState(). Here's an example on how to change the state to a loading state:

Ws_FindFriends->SetWidgetState(EAccelByteWarsWidgetSwitcherState::Loading);

Friend entry widget

Below is the preview of the W_FriendEntry_Starter Blueprint widget. This widget displays friend information, such as display name, avatar, and option buttons. Which will be the entry widget class for the List View in the Find Friend widget.

Potential friend entry widget

As you see from the image above, the option buttons are categorized in a Widget Switcher namely Ws_OptionButtons. The option buttons are the button to do optional actions, such as the invite button to send a friend request. The Widget Switcher will help to display relevant option buttons based on what friend entry type is being displayed.

List View requires the entry widget to implement the IUserObjectListEntry interface. If you look at the parent of this widget's header file, the FriendWidgetEntry_Starter, you can see that it inherited the UAccelByteWarsWidgetEntry, which has the IUserObjectListEntry implemented to it. In order for the widget to work properly as an entry widget, it needs to implement the NativeOnListItemObjectSet function, which is the setup function that the List View will call. This is where all the UI setup needs to be done. We have already set that up for you, so you can simply use it for any List View or call the NativeOnListItemObjectSet function directly to set it up manually.

void UFriendWidgetEntry_Starter::NativeOnListItemObjectSet(UObject* ListItemObject)
{
Super::NativeOnListItemObjectSet(ListItemObject);

CachedFriendData = Cast<UFriendData>(ListItemObject);

// Display display name.
if (!CachedFriendData->DisplayName.IsEmpty())
{
Tb_DisplayName->SetText(FText::FromString(CachedFriendData->DisplayName));
}
else
{
Tb_DisplayName->SetText(FText::FromString(
UTutorialModuleOnlineUtility::GetUserDefaultDisplayName(CachedFriendData->UserId.ToSharedRef().Get())));
}

// Display presence.
Tb_Presence->SetText(FText::FromString(CachedFriendData->GetPresence()));

// Store default brush to be used to reset the avatar brush if needed.
if (!DefaultAvatarBrush.GetResourceObject())
{
DefaultAvatarBrush = Img_Avatar->Brush;
}

// Display avatar image.
const FString AvatarURL = CachedFriendData->AvatarURL;
const FString AvatarId = FBase64::Encode(AvatarURL);

// Try to set avatar image from cache.
FCacheBrush CacheAvatarBrush = AccelByteWarsUtility::GetImageFromCache(AvatarId);
if (CacheAvatarBrush.IsValid())
{
Img_Avatar->SetBrush(*CacheAvatarBrush.Get());
}
// Set avatar image from URL if it is not exists in cache.
else if (!AvatarURL.IsEmpty())
{
AccelByteWarsUtility::GetImageFromURL(
AvatarURL,
AvatarId,
FOnImageReceived::CreateWeakLambda(this, [this](const FCacheBrush ImageResult)
{
Img_Avatar->SetBrush(*ImageResult.Get());
})
);
}
// If no valid avatar, reset it to the default one.
else
{
Img_Avatar->SetBrush(DefaultAvatarBrush);
}

// Display options based on friend's invitation status.
Ws_OptionButtons->SetActiveWidgetIndex((uint8)CachedFriendData->Status);

// Show the reason why the player cannot send invitation request.
Btn_Invite->SetVisibility(!CachedFriendData->bCannotBeInvited ? ESlateVisibility::Visible : ESlateVisibility::Collapsed);
Tb_CannotInviteMessage->SetVisibility(CachedFriendData->bCannotBeInvited ? ESlateVisibility::Visible : ESlateVisibility::Collapsed);
Tb_CannotInviteMessage->SetText(FText::FromString(CachedFriendData->ReasonCannotBeInvited));
}

Since you will use this widget to display found potential friends result, the invite button will be displayed automatically, thanks to the function above.

Below are the declarations of the components used by this widget. The declarations can be found in the FriendWidgetEntry_Starter class header file.

protected:
UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UImage* Img_Avatar;

UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UTextBlock* Tb_DisplayName;

UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UWidgetSwitcher* Ws_OptionButtons;

UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional, BlueprintProtected = true, AllowPrivateAccess = true))
UCommonButtonBase* Btn_Invite;

Ready The UI

In this section, you will learn how to prepare the widgets mentioned before, so you can follow along with the tutorial.

  1. Open the FriendWidgetEntry_Starter class CPP file and navigate to the OnInviteButtonClicked function. This function will be triggered when the invite button is clicked. Later, you will call the functionality to send a friend invitation request in this function. For now, add the following log as the placeholder.

    void UFriendWidgetEntry_Starter::OnInviteButtonClicked()
    {
    // TODO: Call send friend request here.
    UE_LOG_FRIENDS_ESSENTIALS(Warning, TEXT("Send a friend request is not yet implemented."));
    }
  2. Next, open the FindFriendsWidget_Starter class CPP file and navigate to the OnSearchBarCommitted function. This function will be called when you submit any keyword on the W_FindFriends_Starter's search bar. Later, you will call the functionality to show the found potential friends here. For now, add the following log as the placeholder.

    void UFindFriendsWidget_Starter::OnSearchBarCommitted(const FText& Text, ETextCommit::Type CommitMethod)
    {
    // TODO: Get and display find friend result here.
    UE_LOG_FRIENDS_ESSENTIALS(Warning, TEXT("Find friends is not yet implemented."));
    }
  3. Now, build your project and open it in the Unreal Engine Editor. In the Unreal Engine Editor, go to /Content/TutorialModules/Social/FriendsEssentials/. There, you will find a data asset called DA_FriendsEssentials. Open it and enable the Is Starter Mode Active. Then, save the data asset again. This will activate friends-related widgets including the widgets mentioned before, so you can navigate through them when you play the game.

    Activate Tutorial Module Data Asset starter mode

  4. Now, try to play the game in the Unreal Engine Editor and you should be able to navigate like the image below. Then, try to find a friend, you should be able to see the log you just added earlier.

    Tutorial Module UIs quick test

    LogFriendsEssentials: Warning: Find friends is not yet implemented.
  5. Congratulations! You set up the widgets correctly. Move on to the next section where you will implement find potential friends functionalities.

Resources