Put it all together - All time leaderboard - (Unity module)
Connect the UI to display leaderboard rankings
Open
LeaderboardSelectionMenu_Starter.cs
.Add a local variable to hold the reference of
LeaderboardEssentialsWrapper_Starter
and initialize it by using the utility class calledTutorialModuleManager
to get the module class.private LeaderboardEssentialsWrapper_Starter leaderboardWrapper;
private void Start()
{
...
leaderboardWrapper = TutorialModuleManager.Instance.GetModuleClass<LeaderboardEssentialsWrapper_Starter>();
}Prepare for the use of the wrapper function. Create a new callback function that will instantiate the buttons based on the leaderboard list query result, and bind the button callback function you created earlier to the buttons. You are using the same namespace for both Unity and Unreal Engine Byte Wars, so you need to filter the result to only query the
Unity
;leaderboard based on the leaderboard names.private void OnGetLeaderboardListCompleted(Result<LeaderboardPagedListV3> result)
{
if (result.IsError) return;
foreach (LeaderboardDataV3 leaderboardData in result.Value.Data)
{
if (!leaderboardData.Name.Contains("Unity")) continue;
Button leaderboardButton =
Instantiate(leaderboardItemButtonPrefab, leaderboardListPanel).GetComponent<Button>();
TMP_Text leaderboardButtonText = leaderboardButton.GetComponentInChildren<TMP_Text>();
leaderboardButtonText.text = leaderboardData.Name.Replace("Unity Leaderboard ", "");
leaderboardButton.onClick.AddListener(() => ChangeToLeaderboardCycleMenu(leaderboardData.LeaderboardCode));
}
}Create another new function to call the wrapper function to get the leaderboard list and bind it with the callback function you just created.
private void DisplayLeaderboardList()
{
leaderboardWrapper.GetLeaderboardList(OnGetLeaderboardListCompleted);
}Call the
DisplayLeaderboardList()
function insideStart()
for updating the leaderboard list value right after opening the menu.private void Start()
{
...
DisplayLeaderboardList();
}Create a new function called
OnEnable()
and call theDisplayLeaderboardList()
function there to make sure the ranking list value updates every time you open the Leaderboards Menu.private void OnEnable()
{
if (!leaderboardWrapper) return;
DisplayLeaderboardList();
}
Connect the UI to display current user rankings
Open the
LeaderboardMenu_Starter.cs
.Add two local variables to hold the references to
LeaderboardEssentialsWrapper_Starter
andAuthEssentialsWrapper
. You will initialize them by using the utility class calledTutorialModuleManager
to get the module class.private LeaderboardEssentialsWrapper_Starter leaderboardWrapper;
private AuthEssentialsWrapper authWrapper;private void Start()
{
...
leaderboardWrapper = TutorialModuleManager.Instance.GetModuleClass<LeaderboardEssentialsWrapper_Starter>();
authWrapper = TutorialModuleManager.Instance.GetModuleClass<AuthEssentialsWrapper>();
}Define the following variables that store the required values for requesting the ranking list from AccelByte Gaming Services (AGS):
noteTokenData
is a class that contains all detailed information of the current user. Its values are returned upon a successful login.private TokenData currentUserData;
private string currentLeaderboardCode;
private LeaderboardCycleMenu_Starter.LeaderboardCycleType currentCycleType;Create a function that initializes these variables by getting them from the other leaderboard menu and the
AuthEssentialsWrapper
.private void InitializeLeaderboardRequiredValues()
{
currentUserData = authWrapper.userData;
currentLeaderboardCode = LeaderboardSelectionMenu_Starter.chosenLeaderboardCode;
currentCycleType = LeaderboardCycleMenu_Starter.chosenCycleType;
}You also need to define constant variables to limit the range of the leaderboard query to the top 10 players only.
private const int QUERY_OFFSET = 0;
private const int QUERY_LIMIT = 10;Create a function that handles the instantiation of the
RankingEntryPanel
that holds each player ranking info. AdduserId
,playerName
, andplayerScore
as parameters since you will display these values. Also, update theUserRankingPanel
as well if it's the current user ranking data.public void InstantiateRankingEntry(string userId, int playerRank, string playerName, float playerScore)
{
RankingEntryPanel rankingEntryPanel =
Instantiate(rankingEntryPanelPrefab, rankingListPanel).GetComponent<RankingEntryPanel>();
rankingEntryPanel.SetRankingDetails(userId, playerRank, playerName, playerScore);
if (userId != currentUserData.user_id) return;
// Highlight players ranking entry and set ranking details to user ranking panel
rankingEntryPanel.SetPanelColor(new Color(1.0f, 1.0f, 1.0f, 0.098f)); // rgba 255,255,255,25
userRankingPanel.SetRankingDetails(userId, playerRank, playerName, playerScore);
}Since the
GetRankings()
function only returns an array of user IDs, you need to use theBulkGetUserInfo()
function in theAuthEssentialsWrapper
to get their display names. You will first create a callback function to handle the get user info result. In this function, you also call theGetUserRanking()
function in theLeaderboardEssentialsWrapper_Starter
if you can't find the current player's user ID in the leaderboard ranking list.private void OnBulkGetUserInfoCompleted(Result<ListBulkUserInfoResponse> result,
Dictionary<string, float> userRankInfos)
{
// Dict key = userId, value = displayName
Dictionary<string, string> userDisplayNames = result.Value.data.ToDictionary(userInfo => userInfo.userId, userInfo => userInfo.displayName);
int rankOrder = 0;
foreach (string userId in userRankInfos.Keys)
{
rankOrder += 1;
InstantiateRankingEntry(userId, rankOrder, userDisplayNames[userId], userRankInfos[userId]);
}
if (userRankInfos.Keys.Contains(currentUserData.user_id)) return;
// Get player ranking if player not on the ranking list
leaderboardWrapper.GetUserRanking(currentUserData.user_id, currentLeaderboardCode,
OnGetUserRankingCompleted);
}Create the callback function that handles the leaderboard ranking query result. Remember, you need to call the
BulkGetUserInfo()
function in theAuthEssentialsWrapper
to get the display names of the players in the ranking list.public void OnGetRankingsCompleted(Result<LeaderboardRankingResult> result)
{
if (result.IsError) return;
// Set placeholder text active to true if list empty
placeholderText.gameObject.SetActive(result.Value.data.Length <= 0);
// Store the ranking result's userIds and points to a Dictionary
Dictionary<string, float> userRankInfos =
result.Value.data.ToDictionary(userPoint => userPoint.userId, userPoint => userPoint.point);
// Get the players' display name from the provided user ids
authWrapper.BulkGetUserInfo(userRankInfos.Keys.ToArray(),
authResult => OnBulkGetUserInfoCompleted(authResult, userRankInfos));
}Create a new function to call the
DisplayRankingList()
function if the leaderboard's cycle period isAllTime
.private void DisplayRankingList()
{
InitializeLeaderboardRequiredValues();
if (currentCycleType is LeaderboardCycleMenu_Starter.LeaderboardCycleType.AllTime)
{
leaderboardWrapper.GetRankings(currentLeaderboardCode, OnGetRankingsCompleted, QUERY_OFFSET, QUERY_LIMIT);
}
}Create a new callback function that handles the
GetUserRanking()
to display the current user ranking within the leaderboard.private void OnGetUserRankingCompleted(Result<UserRankingDataV3> result)
{
if (result.IsError) return;
if (currentCycleType != LeaderboardCycleMenu_Starter.LeaderboardCycleType.AllTime) return;
UserRanking allTimeUserRank = result.Value.AllTime;
userRankingPanel.SetRankingDetails(currentUserData.user_id, allTimeUserRank.rank,
currentUserData.display_name, allTimeUserRank.point);
}Create a function called
OnEnable()
and callDisplayRankingList()
there to display the ranking list. Also, callDisplayRankingList()
in theStart()
function.private void OnEnable()
{
if (!leaderboardWrapper || !authWrapper) return;
DisplayRankingList();
}private void Start()
{
...
DisplayRankingList();
}
Resources
- GitHub Link to the files in the Byte Wars repository: