Put it all together - Add friends - (Unity module)
Connect the UI to display sent and received friend request list, accept, decline, and cancel friend request
This section will cover both FriendRequestMenuHandler_Starter.cs
for showing incoming friend request and SentFriendRequestMenuHandler_Starter.cs
for showing outgoing friend request.
Open
FriendRequestMenuHandler_Starter.cs
andSentFriendRequestMenuHandler_Starter.cs
and add a field that will hold the reference to the SDK wrapper.- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private FriendEssentialsWrapper_Starter _friendEssentialsWrapper;
private FriendEssentialsWrapper_Starter _friendEssentialsWrapper;
Update the
Awake
function in each file with the following code:- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void Awake()
{
_friendEssentialsWrapper = TutorialModuleManager.Instance.GetModuleClass<FriendEssentialsWrapper_Starter>();
}private void Awake()
{
_friendEssentialsWrapper = TutorialModuleManager.Instance.GetModuleClass<FriendEssentialsWrapper_Starter>();
}Go to
OnEnable()
in each file and update it with the following code:- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void OnEnable()
{
if(_friendEssentialsWrapper==null)
_friendEssentialsWrapper = TutorialModuleManager.Instance.GetModuleClass<FriendEssentialsWrapper_Starter>();
GetFriendRequest();
}private void OnEnable()
{
if(_friendEssentialsWrapper==null)
_friendEssentialsWrapper = TutorialModuleManager.Instance.GetModuleClass<FriendEssentialsWrapper_Starter>();
GetFriendRequest();
}In each file, update the
GetFriendRequest
function that you already created with the following code:- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void GetFriendRequest()
{
if (_friendEssentialsWrapper == null) return;
_friendEssentialsWrapper.LoadIncomingFriendRequests(OnLoadIncomingFriendRequestsCompleted);
}private void GetFriendRequest()
{
if (_friendEssentialsWrapper == null) return;
_friendEssentialsWrapper.LoadOutgoingFriendRequests(OnLoadOutgoingRequestsCompleted);
}In each file, to update the friend list based on the invoked event, you will create a function called
UpdateFriendList
. This function will be attached to the event action in theStart
function.- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void UpdateFriendList()
{
if (transform.gameObject.activeSelf)
{
ClearFriendRequestList();
GetFriendRequest();
}
}private void UpdateFriendList()
{
if (transform.gameObject.activeSelf)
{
ClearFriendRequestList();
GetFriendRequest();
}
}In each file, update
Start()
to listen to the action events from theFriendEssentialsWrapper_Starter
class and invoke theUpdateFriendList
function whenever an event is triggered.- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
void Start()
{
_panels = new List<RectTransform>()
{
defaultPanel,
loadingPanel,
loadingSuccessPanel,
loadingFailedPanel
};
backButton.onClick.AddListener(MenuManager.Instance.OnBackPressed);
FriendEssentialsWrapper_Starter.OnIncomingAdded += UpdateFriendList;
}void Start()
{
_panels = new List<RectTransform>()
{
defaultPanel,
loadingPanel,
loadingSuccessPanel,
loadingFailedPanel
};
backButton.onClick.AddListener(MenuManager.Instance.OnBackPressed);
FriendEssentialsWrapper_Starter.OnRejected += UpdateFriendList;
FriendEssentialsWrapper_Starter.OnAccepted += UpdateFriendList;
}In each file, create a callback function to update the user interface (UI) and the data once the friend request loading is finished.
- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void OnLoadIncomingFriendRequestsCompleted(Result<Friends> result)
{
if (!result.IsError)
{
CurrentView = FriendRequestsView.LoadingSuccess;
if (result.Value.friendsId.Length > 0)
{
UserInfo(result.Value);
}
else
{
CurrentView = FriendRequestsView.Default;
}
}
else
{
CurrentView = FriendRequestsView.LoadingFailed;
}
}private void OnLoadOutgoingRequestsCompleted(Result<Friends> result)
{
if (!result.IsError)
{
CurrentView = SentFriendRequestsView.LoadingSuccess;
if (result.Value.friendsId.Length > 0)
{
UserInfo(result.Value);
}
else
{
CurrentView = SentFriendRequestsView.Default;
}
}
else
{
CurrentView = SentFriendRequestsView.LoadingFailed;
}
}You have declared the
UserInfo
function without actually creating the corresponding function. To address this, in each file, create the necessary function that retrieves user information in bulk.- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void UserInfo(Friends friends)
{
_friendEssentialsWrapper.GetBulkUserInfo(friends.friendsId, OnGetBulkUserInfoCompleted);
}private void UserInfo(Friends friends)
{
_friendEssentialsWrapper.GetBulkUserInfo(friends.friendsId, OnGetBulkUserInfoCompleted);
}In each file, create a callback function that will handle the UI update after the
GetBulkUserInfo
loads successfully.- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void OnGetBulkUserInfoCompleted(Result<ListBulkUserInfoResponse> result)
{
if (!result.IsError)
{
GenerateEntryResult(result.Value);
}
}private void OnGetBulkUserInfoCompleted(Result<ListBulkUserInfoResponse> result)
{
if (!result.IsError)
{
GenerateEntryResult(result.Value);
}
}In each file, create a function to generate the Friend Entry component. This component will display the avatar, username, and a button based on the list of user information retrieved earlier.
- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void GenerateEntryResult(ListBulkUserInfoResponse friends)
{
var friendRequestComponent = loadingSuccessPanel.GetChild(0);
Debug.Log(friendRequestComponent.name);
foreach (var baseUserInfo in friends.data)
{
var resultComponent = Instantiate(friendRequestComponent, Vector3.zero, Quaternion.identity, loadingSuccessPanel);
resultComponent.gameObject.SetActive(true);
resultComponent.gameObject.name = baseUserInfo.userId;
var friendEntryComponent = resultComponent.GetComponentInChildren<FriendRequestsEntryHandler>();
friendEntryComponent.friendName.text = String.IsNullOrEmpty(baseUserInfo.displayName) ? "Bytewars Player Headless" : baseUserInfo.displayName;
friendEntryComponent.acceptButton.onClick.AddListener(() =>
{
OnAcceptFriend(baseUserInfo.userId);
});
friendEntryComponent.declineButton.onClick.AddListener(() =>
{
OnDeclineFriend(baseUserInfo.userId);
});
_friendRequest.TryAdd(baseUserInfo.userId, (RectTransform)resultComponent);
RetrieveAvatar(baseUserInfo.userId);
}
}private void GenerateEntryResult(ListBulkUserInfoResponse friends)
{
var friendRequestComponent = loadingSuccessPanel.transform.GetChild(0);
Debug.Log(friendRequestComponent.name);
foreach (var baseUserInfo in friends.data)
{
var resultComponent = Instantiate(friendRequestComponent, Vector3.zero, Quaternion.identity, loadingSuccessPanel);
resultComponent.gameObject.SetActive(true);
resultComponent.gameObject.name = baseUserInfo.userId;
var friendEntryComponent = resultComponent.GetComponentInChildren<SentFriendRequestsEntryHandler>();
friendEntryComponent.friendName.text = String.IsNullOrEmpty(baseUserInfo.displayName) ? "Bytewars Player Headless" : baseUserInfo.displayName;
friendEntryComponent.cancelButton.onClick.AddListener(() =>
{
OnCancelRequest(baseUserInfo.userId);
});
_friendRequest.TryAdd(baseUserInfo.userId, (RectTransform)resultComponent);
RetrieveAvatar(baseUserInfo.userId);
}
}In the previous step, you might have noticed you declared
OnAcceptFriend
andOnCancelRequest
, but haven't yet created the functions. Those functions are to hold the functionalities to accept and reject friend requests. InFriendRequestMenuHandler_Starter.cs
, create both functions with the following code:private void OnDeclineFriend(string userId)
{
_friendEssentialsWrapper.DeclineFriend(userId, result => OnAcceptOrDecline(userId, result));
}
private void OnAcceptFriend(string userId)
{
_friendEssentialsWrapper.AcceptFriend(userId, result => OnAcceptOrDecline(userId, result));
}To handle the result from
OnAcceptFriend
andOnCancelRequest
, create a callback function that will trigger if those functions.private void OnAcceptOrDecline(string userId, Result result)
{
if (!result.IsError)
{
var target = GameObject.Find(userId);
Destroy(target);
}
}In
SentFriendRequestMenuHandler_Starter.cs
, you will notice that you have already declaredOnCancelRequest
. Create a function for this using following code:private void OnCancelRequest(string userId)
{
_friendEssentialsWrapper.CancelFriendRequests(userId, result => OnCancelRequestCompleted(userId, result));
}Still in
SentFriendRequestMenuHandler_Starter.cs
, create a callback for_friendEssentialsWrapper.CancelFriendRequests
. This callback will update the UI if a player cancels the outgoing friend request.private void OnCancelRequestCompleted(string userId, Result result)
{
if (!result.IsError)
{
var target = GameObject.Find(userId);
Destroy(target);
}
}Create the
RetrieveAvatar
function for both files,FriendRequestMenuHandler_Starter.cs
andSentFriendRequestMenuHandler_Starter.cs
. This function will retrieve the avatar for each friend.- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void RetrieveAvatar(string userId)
{
loadingPanel.gameObject.SetActive(true);
_friendEssentialsWrapper.GetUserAvatar(userId, result => OnGetAvatarCompleted(userId, result));
}private void RetrieveAvatar(string userId)
{
loadingPanel.gameObject.SetActive(true);
_friendEssentialsWrapper.GetUserAvatar(userId, result => OnGetAvatarCompleted(userId, result));
}Create a callback function in both files to handle the UI changes based on the avatar obtained from the previous step.
- FriendRequestMenuHandler_Starter.cs
- SentFriendRequestMenuHandler_Starter.cs
private void OnGetAvatarCompleted(string userId, Result<Texture2D> result)
{
if (!result.IsError)
{
var incomingRequestEntry = GameObject.Find(userId);
incomingRequestEntry.GetComponent<FriendRequestsEntryHandler>().friendImage.sprite = Sprite.Create(result.Value,
new Rect(0f, 0f, result.Value.width, result.Value.height), Vector2.zero);
}
loadingPanel.gameObject.SetActive(false);
}private void OnGetAvatarCompleted(string userId, Result<Texture2D> result)
{
if (!result.IsError)
{
var outgoingRequestEntry = GameObject.Find(userId);
outgoingRequestEntry.GetComponent<SentFriendRequestsEntryHandler>().friendImage.sprite = Sprite.Create(result.Value,
new Rect(0f, 0f, result.Value.width, result.Value.height), Vector2.zero);
}
loadingPanel.gameObject.SetActive(false);
}
Resources
- The files used in this tutorial are available in the Unity Byte Wars GitHub repository.
- Assets/Resources/Modules/FriendEssentials/Prefabs/FriendRequest/FriendRequestMenuCanvas_Starter.prefab
- Assets/Resources/Modules/FriendEssentials/Scripts/UI/FriendRequestMenuHandler_Starter.cs
- Assets/Resources/Modules/FriendEssentials/Prefabs/FriendRequest/FriendRequestEntryComponent.prefab
- Assets/Resources/Modules/FriendEssentials/Scripts/UI/FriendRequestsEntryHandler.cs
- Assets/Resources/Modules/FriendEssentials/Prefabs/SentFriendRequest/SentFriendRequestMenuCanvas_Starter.prefab
- Assets/Resources/Modules/FriendEssentials/Scripts/UI/SentFriendRequestMenuHandler_Starter.cs
- Assets/Resources/Modules/FriendEssentials/Prefabs/SentFriendRequest/SentFriendRequestEntryComponent.prefab
- Assets/Resources/Modules/FriendEssentials/Scripts/UI/SentFriendRequestsEntryHandler.cs