Put it all together - Search for players - (Unity module)
Connect the UI to search player
Open
FindFriendsMenuHandler_Starter.cs
and declare theFriendsEssentialsWrapper_Starter
class as a private field.private FriendsEssentialsWrapper_Starter friendsEssentialsWrapper;
To initiate the
friendsEssentialsWrapper
functionality at the start, navigate to theStart()
function and add the following code:private void Start()
{
friendsEssentialsWrapper = TutorialModuleManager.Instance.GetModuleClass<FriendsEssentialsWrapper_Starter>();
}Find the
FindFriend()
function and replace the existing implementation with the following code. In Byte Wars, once a user performs a search, it will treat the given value as a friend code first. If it fails, then it will treat it as display name. Here, theOnUsersFriendCodeFound()
function is called to check and display the user information.private void FindFriend(string query)
{
if (string.IsNullOrEmpty(friendSearchBar.text) || string.IsNullOrEmpty(friendSearchBar.text))
{
return;
}
CurrentView = FindFriendsView.Loading;
friendSearchBar.enabled = false;
ClearSearchPanel();
friendsEssentialsWrapper.GetUserByFriendCode(query, result =>
{
OnUsersFriendCodeFound(result, query, fallbackAction: () =>
{
BytewarsLogger.Log("Friend code not found, searching by exact display name");
friendsEssentialsWrapper.GetUserByExactDisplayName(query, result => OnUsersDisplayNameFound(result, query));
});
});
}Create a callback function called
OnUsersFriendCodeFound()
to handle the data, UI changes, and fallback action when a response to the search user by friend code is received. If the friend code is not found, it will attempt to trigger the fallback action first. If there's no fallback action, then it will show a message that the query is not found.private void OnUsersFriendCodeFound(Result<PublicUserData> result, string query, Action fallbackAction = null)
{
friendSearchBar.enabled = true;
if (result.IsError)
{
if (fallbackAction is not null)
{
fallbackAction.Invoke();
return;
}
CurrentView = FindFriendsView.LoadFailed;
string queryNotFoundMessage = FriendsHelper.QueryNotFoundMessage.Replace("%QUERY%", query);
loadingFailedPanel.GetComponentInChildren<TMP_Text>().text = queryNotFoundMessage;
return;
}
PublicUserData userData = result.Value;
if (userData.userId == friendsEssentialsWrapper.PlayerUserId)
{
BytewarsLogger.Log("Found friend code with self entry");
CurrentView = FindFriendsView.LoadFailed;
loadingFailedPanel.GetComponentInChildren<TMP_Text>().text = FriendsHelper.FriendRequestSelfMessage;
return;
}
SendFriendInvitation(userData.userId, usingFriendCode: true);
CreateFriendEntry(userData.userId, userData.displayName);
}Create another callback function called
OnUsersDisplayNameFound()
to handle the data and UI changes when a response to the search (using a display name) is received. If a user was found, the results will be shown. If not, it will show a message that the query is not found.private void OnUsersDisplayNameFound(Result<PublicUserInfo> result, string query)
{
if (result.IsError)
{
CurrentView = FindFriendsView.LoadFailed;
string queryNotFoundMessage = FriendsHelper.QueryNotFoundMessage.Replace("%QUERY%", query);
loadingFailedPanel.GetComponentInChildren<TMP_Text>().text = queryNotFoundMessage;
return;
}
CreateFriendEntry(result.Value.userId, result.Value.displayName);
}Create a function called
CreateFriendEntry()
to instantiate theFriendEntryComponent.prefab
and show the user avatar, display name, and send invite button.private void CreateFriendEntry(string userId, string displayName)
{
if (userId == friendsEssentialsWrapper.PlayerUserId)
{
BytewarsLogger.Log("Skipping self entry");
CurrentView = FindFriendsView.Default;
return;
}
GameObject playerEntry = Instantiate(friendEntryPrefab, resultContentPanel);
playerEntry.name = userId;
if (string.IsNullOrEmpty(displayName))
{
string truncatedUserId = userId[..5];
displayName = $"Player-{truncatedUserId}";
}
FindFriendsEntryHandler playerEntryHandler = playerEntry.GetComponent<FindFriendsEntryHandler>();
playerEntryHandler.UserId = userId;
playerEntryHandler.FriendName.text = displayName;
userResult = playerEntry;
}
Connect the UI to display friend code
Open
FindFriendsMenuHandler_Starter.cs
and create a function calledSetFriendCodeText()
to display the friend code of the player.private void SetFriendCodeText(string friendCodeString)
{
if (string.IsNullOrEmpty(friendCodeString))
{
friendCode.SetText(FriendsHelper.FriendCodePreloadMessage);
return;
}
friendCode.SetText(friendCodeString);
}Navigate to the
Start()
function and add the following code to display the player's friend code.private void Start()
{
friendsEssentialsWrapper = TutorialModuleManager.Instance.GetModuleClass<FriendsEssentialsWrapper_Starter>();
SetFriendCodeText(friendsEssentialsWrapper.PlayerFriendCode);
}
Connect the UI to check friendship status
In Byte Wars, once the search result was received, the game will check the friendship status first and only enable the invite button if the searched user is NotFriend
with the local user.
Open
FindFriendsMenuHandler_Starter.cs
and create a function calledCheckFriendshipStatus()
to check the friendship status between the player and the searched player.private void CheckFriendshipStatus(string userId)
{
friendsEssentialsWrapper.GetFriendshipStatus(userId, OnGetFriendshipStatusCompleted);
}Create a callback function called
OnGetFriendshipStatusCompleted()
to handle the data and UI changes when the friendship status is retrieved. The result will determine the state of the current view and the status message displayed on the searched player UI entry.private void OnGetFriendshipStatusCompleted(Result<FriendshipStatus> result)
{
if (userResult is null)
{
return;
}
FindFriendsEntryHandler entryHandler = userResult.GetComponent<FindFriendsEntryHandler>();
if (result.IsError)
{
entryHandler.FriendStatus.text = FriendsHelper.ErrorStatusMessage;
BytewarsLogger.LogWarning($"Unable to get friendship status: {result.Error.Message}");
CurrentView = FindFriendsView.LoadFailed;
return;
}
CurrentView = FindFriendsView.LoadSuccess;
RelationshipStatusCode friendshipStatus = result.Value.friendshipStatus;
string statusMessage = FriendsHelper.StatusMessageMap[friendshipStatus];
entryHandler.FriendStatus.text = statusMessage;
entryHandler.SendInviteButton.interactable = friendshipStatus is RelationshipStatusCode.NotFriend;
if (friendshipStatus is RelationshipStatusCode.Outgoing)
{
entryHandler.SendInviteButton.GetComponentInChildren<TMP_Text>().text = FriendsHelper.RequestSentMessage;
}
}Navigate to the
CreateFriendEntry()
function and add the following code to call theCheckFriendshipStatus()
function after creating the friend entry as shown below.private void CreateFriendEntry(string userId, string displayName)
{
//...
userResult = playerEntry;
CheckFriendshipStatus(userId);
}
Connect the UI to send friend invitation
Open
FindFriendsMenuHandler_Starter.cs
and create a function calledSendFriendInvitation()
to send a friend invitation to the searched player. The function will show a loading prompt while sending the friend request.private void SendFriendInvitation(string userId, bool usingFriendCode = false)
{
if (!usingFriendCode)
{
MenuManager.Instance.PromptMenu.ShowLoadingPrompt(FriendsHelper.SendingFriendRequestMessage);
}
friendsEssentialsWrapper.SendFriendRequest(userId, result => OnSendRequestComplete(result, usingFriendCode));
}Create a callback function called
OnSendRequestComplete()
to handle the data and UI changes when the friend request response is received. The result will update the state of the send invite button and the status message displayed on the UI.private void OnSendRequestComplete(IResult result, bool usingFriendCode = false)
{
if (result.IsError)
{
if (usingFriendCode)
{
BytewarsLogger.LogWarning($"Unable to send friend request using friend code: {result.Error.Message}");
return;
}
string errorMessage = FriendsHelper.DefaultSendFriendRequestErrorMessage;
if (FriendsHelper.SendFriendRequestErrorMessages.TryGetValue(result.Error.Code, out string message))
{
errorMessage = message;
}
MenuManager.Instance.PromptMenu.ShowPromptMenu(FriendsHelper.PromptErrorTitle, errorMessage, "OK", null);
return;
}
string promptDetailsMessage = usingFriendCode
? FriendsHelper.FriendRequestSentFriendCodeMessage
: FriendsHelper.FriendRequestSentDetailsMessage;
MenuManager.Instance.PromptMenu.ShowPromptMenu(FriendsHelper.PromptMessageTitle,
promptDetailsMessage, "OK", null);
if (!userResult.TryGetComponent(out FindFriendsEntryHandler entryHandler))
{
return;
}
entryHandler.SendInviteButton.interactable = false;
entryHandler.SendInviteButton.GetComponentInChildren<TMP_Text>().text = FriendsHelper.RequestSentMessage;
entryHandler.FriendStatus.text = FriendsHelper.StatusMessageMap[RelationshipStatusCode.Outgoing];
}Navigate to the
CreateFriendEntry()
function and add the following code to call theSendFriendInvitation()
function when the send invite button is clicked.private void CreateFriendEntry(string userId, string displayName)
{
//...
playerEntryHandler.FriendName.text = displayName;
playerEntryHandler.SendInviteButton.onClick.AddListener(() => SendFriendInvitation(userId));
userResult = playerEntry;
//...
}
Connect the UI to display avatar of the searched player
Open
FindFriendsMenuHandler_Starter.cs
and create a function calledRetrieveUserAvatar()
to obtain the avatar of the searched player.private void RetrieveUserAvatar(string userId)
{
friendsEssentialsWrapper.GetUserAvatar(userId, result => OnGetAvatarCompleted(result, userId));
}Create a callback function called
OnGetAvatarCompleted()
to handle the data and UI changes when the avatar is retrieved. The result will update the avatar image displayed on the UI.private void OnGetAvatarCompleted(Result<Texture2D> result, string userId)
{
if (result.IsError)
{
BytewarsLogger.LogWarning($"Unable to get avatar for user Id: {userId}, " +
$"Error Code: {result.Error.Code}, " +
$"Error Message: {result.Error.Message}");
return;
}
if (result.Value == null || userResult == null)
{
return;
}
Image entryImage = userResult.GetComponent<FindFriendsEntryHandler>().FriendImage;
Rect imageRect = new Rect(0f, 0f, result.Value.width, result.Value.height);
entryImage.sprite = Sprite.Create(result.Value, imageRect, Vector2.zero);
}Navigate to the
CreateFriendEntry()
function and add the following code to call theRetrieveUserAvatar()
function after creating the friend entry.private void CreateFriendEntry(string userId, string displayName)
{
//...
userResult = playerEntry;
CheckFriendshipStatus(userId);
RetrieveUserAvatar(userId);
}
Resources
- The files used in this tutorial are available in the Unity Byte Wars GitHub repository.
- Assets/Resources/Modules/FriendsEssentials/Scripts/UI/FindFriendsMenuHandler_Starter.cs
- Assets/Resources/Modules/FriendsEssentials/Prefabs/FindUser/FindFriendsMenuCanvas_Starter.prefab
- Assets/Resources/Modules/FriendsEssentials/Prefabs/FindUser/FriendEntryComponent.prefab
- Assets/Resources/Modules/FriendsEssentials/Scripts/UI/FriendResultPanelHandler.cs