Put it all together - Display friend list - (Unity module)
Connect the UI to get friend list
Open
FriendsMenuHandler_Starter.cs
and declare theFriendsEssentialsWrapper_Starter
class as a private variable.private FriendsEssentialsWrapper_Starter friendsEssentialsWrapper;
Replace the existing
LoadFriendList
function with the code below to call theGetFriendList
function from theFriendsEssentialsWrapper_Starter
class. This will trigger the actual friend list retrieval from the backend.private void LoadFriendList()
{
CurrentView = FriendsView.Loading;
ClearFriendList();
friendsEssentialsWrapper.GetFriendList(OnLoadFriendListCompleted);
}Replace the existing
OnLoadFriendListCompleted
callback function with the code below to handle the result.private void OnLoadFriendListCompleted(Result<Friends> result)
{
if (result.IsError)
{
CurrentView = FriendsView.LoadFailed;
return;
}
if (result.Value.friendsId.Length <= 0)
{
CurrentView = FriendsView.Default;
return;
}
GetBulkUserInfo(result.Value);
}Create a function called
GetBulkUserInfo()
to get the user information from the list of friend IDs.private void GetBulkUserInfo(Friends friends)
{
friendsEssentialsWrapper.GetBulkUserInfo(friends.friendsId, OnGetBulkUserInfoCompleted);
}Create a callback function called
OnGetBulkUserInfoCompleted()
to handle the result.private void OnGetBulkUserInfoCompleted(Result<ListBulkUserInfoResponse> result)
{
if (result.IsError)
{
return;
}
ClearFriendList();
CurrentView = FriendsView.LoadSuccess;
PopulateFriendList(result.Value.data);
}Create a function called
PopulateFriendRequestList()
to populate the friend list.private void PopulateFriendList(params BaseUserInfo[] userInfo)
{
foreach (BaseUserInfo baseUserInfo in userInfo)
{
CreateFriendEntry(baseUserInfo.userId, baseUserInfo.displayName);
}
}Create a function called
CreateFriendEntry()
to create a friend entry for each friend. If the friend's display name is empty, the function will use the first five characters of the user ID as the display name.private void CreateFriendEntry(string userId, string displayName)
{
GameObject playerEntry = InstantiateToColumn(friendEntryPrefab);
playerEntry.name = userId;
if (string.IsNullOrEmpty(displayName))
{
string truncatedUserId = userId[..5];
displayName = $"Player-{truncatedUserId}";
}
FriendsEntryComponentHandler playerEntryHandler = playerEntry.GetComponent<FriendsEntryComponentHandler>();
playerEntryHandler.UserId = userId;
playerEntryHandler.FriendName.text = displayName;
friendEntries.Add(userId, playerEntry);
}Replace the existing
OnEnable()
function with the code below to initialize thefriendsEssentialsWrapper
variable and call theLoadFriendList()
function.private void OnEnable()
{
if (friendsEssentialsWrapper == null)
{
friendsEssentialsWrapper = TutorialModuleManager.Instance.GetModuleClass<FriendsEssentialsWrapper_Starter>();
}
if (friendsEssentialsWrapper == null)
{
BytewarsLogger.LogWarning("FriendsEssentialsWrapper is not enabled");
return;
}
if (CurrentView == FriendsView.Loading)
{
BytewarsLogger.Log("Already loading friend list");
return;
}
LoadFriendList();
}
Connect the UI to display avatars of friends
Open
FriendsMenuHandler_Starter.cs
and create a function calledRetrieveUserAvatar()
to get the user avatar.private void RetrieveUserAvatar(string userId)
{
friendsEssentialsWrapper.GetUserAvatar(userId, result => OnGetAvatarCompleted(result, userId));
}Create a callback function called
OnGetAvatarCompleted()
to handle the result.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 || !friendEntries.TryGetValue(userId, out GameObject friendEntry))
{
return;
}
Image friendImage = friendEntry.GetComponent<FriendsEntryComponentHandler>().FriendImage;
Rect imageRect = new Rect(0f, 0f, result.Value.width, result.Value.height);
friendImage.sprite = Sprite.Create(result.Value, imageRect, Vector2.zero);
}Update the
CreateFriendEntry()
function to call theRetrieveUserAvatar()
function. Add the code below:private void CreateFriendEntry(string userId, string displayName)
{
//...
friendEntries.Add(userId, playerEntry);
RetrieveUserAvatar(userId);
}
Connect the entry to the friend details menu
Open
FriendsMenuHandler_Starter.cs
and create a function calledOnFriendEntryClicked()
to handle the friend entry click event. This function will instantiate the friend details menu canvas, pass the user information, and change the menu to the friend details menu.private void OnFriendEntryClicked(string userId, string displayName,
FriendsEntryComponentHandler playerEntryHandler)
{
AssetEnum friendDetailCanvas = friendDetailMenuCanvas;
if (friendDetailCanvas is AssetEnum.FriendDetailsMenuCanvas)
{
MenuManager.Instance.InstantiateCanvas(friendDetailCanvas);
}
if (!MenuManager.Instance.AllMenu.TryGetValue(friendDetailCanvas, out MenuCanvas menuCanvas))
{
BytewarsLogger.LogWarning($"Unable to find {friendDetailCanvas} in menu manager");
return;
}
if (menuCanvas.gameObject.TryGetComponent(out FriendDetailsMenuHandler friendDetailMenu))
{
friendDetailMenu.UserId = userId;
friendDetailMenu.FriendImage.sprite = playerEntryHandler.FriendImage.sprite;
friendDetailMenu.FriendDisplayName.text = displayName;
}
MenuManager.Instance.ChangeToMenu(friendDetailCanvas);
}Update the
CreateFriendEntry()
function to add an event listener to the friend entry to call theOnFriendEntryClicked()
function. Add the code below.private void CreateFriendEntry(string userId, string displayName)
{
//...
playerEntryHandler.FriendName.text = displayName;
Button friendButton = playerEntry.GetComponent<Button>();
friendButton.onClick.AddListener(() => OnFriendEntryClicked(userId, displayName, playerEntryHandler));
friendEntries.Add(userId, playerEntry);
//...
}
Connect the UI to Friends Action Events
In this section, you will use the static action events that you have used in the Add friends and Manage friends modules. If you have not completed or do not intend to complete those modules, you will only forfeit the real-time friend list update feature.
Open
FriendsMenuHandler_Starter.cs
and create a function calledOnFriendListUpdate()
. It will trigger theLoadFriendList
function, updating the current displayed list.private void OnFriendListUpdate(string userId)
{
if (!gameObject.activeSelf)
{
return;
}
LoadFriendList();
}Update the
Awake
function to bind the action events in the wrapper to theOnFriendListUpdate
function. Add the code below:private void Awake()
{
//...
backButton.onClick.AddListener(MenuManager.Instance.OnBackPressed);
// Bind to both starter and non starter to allow mixed usage of starter and non
FriendsEssentialsWrapper.OnRequestAccepted += OnFriendListUpdate;
ManagingFriendsWrapper.OnPlayerUnfriended += OnFriendListUpdate;
ManagingFriendsWrapper.OnPlayerBlocked += OnFriendListUpdate;
FriendsEssentialsWrapper_Starter.OnRequestAccepted += OnFriendListUpdate;
ManagingFriendsWrapper_Starter.OnPlayerUnfriended += OnFriendListUpdate;
ManagingFriendsWrapper_Starter.OnPlayerBlocked += OnFriendListUpdate;
//...
}Replace the
OnDestroy
function with the code below to unbind those events when the UI is destroyed.private void OnDestroy()
{
FriendsEssentialsWrapper.OnRequestAccepted -= OnFriendListUpdate;
ManagingFriendsWrapper.OnPlayerUnfriended -= OnFriendListUpdate;
ManagingFriendsWrapper.OnPlayerBlocked -= OnFriendListUpdate;
FriendsEssentialsWrapper_Starter.OnRequestAccepted -= OnFriendListUpdate;
ManagingFriendsWrapper_Starter.OnPlayerUnfriended -= OnFriendListUpdate;
ManagingFriendsWrapper_Starter.OnPlayerBlocked -= OnFriendListUpdate;
}
Resources
- The files used in this tutorial are available in the Unity Byte Wars GitHub repository.