Unreal Engine Module - Search Player - Add find friends menu
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
.
- Header file can be found in
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
.
- Header file can be found in
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:
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.
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.
Open the
FriendWidgetEntry_Starter
class CPP file and navigate to theOnInviteButtonClicked
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."));
}Next, open the
FindFriendsWidget_Starter
class CPP file and navigate to theOnSearchBarCommitted
function. This function will be called when you submit any keyword on theW_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."));
}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 calledDA_FriendsEssentials
. Open it and enable theIs 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.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.
LogFriendsEssentials: Warning: Find friends is not yet implemented.
Congratulations! You set up the widgets correctly. Move on to the next section where you will implement find potential friends functionalities.
Resources
- The files used in this tutorial section are available in the Byte Wars GitHub repository.
- AccelByteWars/Content/TutorialModules/Social/FriendsEssentials/DA_FriendsEssentials.uasset
- AccelByteWars/Content/TutorialModules/Social/FriendsEssentials/UI/W_FindFriends_Starter.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FindFriendsWidget_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FindFriendsWidget_Starter.cpp
- AccelByteWars/Content/TutorialModules/Social/FriendsEssentials/UI/W_FriendEntry_Starter.uasset
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FriendWidgetEntry_Starter.h
- AccelByteWars/Source/AccelByteWars/TutorialModules/Social/FriendsEssentials/UI/FriendWidgetEntry_Starter.cpp