Skip to content

Leaderboards

Description

This class is responsible for handling user leaderboards. After the leaderboard entries (user rank, GalaxyID and score) are fetched, we store them in a private local list of object arrays named leaderboardEntries. To make it easily accessible from outside of the Leaderboards class, we create a public LeaderboardEntries get method as well.

Important

Similarly as with statistics and achievements, you need to request and receive leaderboards definitions before calling any other methods related to them. You can request leaderboard definitions by calling RequestLeaderboards().

Class Initialization and Termination

In our demo game, the Leaderboards class is instantiated by adding the Leaderboards script to GalaxyManager GameObject with the GalaxyManager.StartLeaderboards() method called within GalaxyManager.AuthenticationListener.OnAuthSuccess() callback. To make sure that the user is online (Internet connection is required to use leaderboards), we check the user’s IsLoggedOn status before enabling Leaderboards.

Definitions of Listeners

LeaderboardsRetrieveListener

    private class LeaderboardsRetrieveListener : GlobalLeaderboardsRetrieveListener
    {
        public bool retrieved = false;

        public override void OnLeaderboardsRetrieveSuccess()
        {
            Debug.Log("Leaderboard definitions retrieved");
            retrieved = true;
        }
        public override void OnLeaderboardsRetrieveFailure(FailureReason failureReason)
        {
            Debug.LogWarning("Leaderboard definitions couldn't be retrieved, for reason: " + failureReason);
        }

    }

It listens for an event of receiving definitions of all available leaderboards. You should request these definitions by calling GalaxyInstance.Stats().RequestLeaderboards().

Once the leaderboards definitions are retrieved, the OnLeaderboardsRetrieveSuccess() event is fired and we set the LeaderboardsRetrieveListener.retrieved Boolean to true. If the definitions could not be retrieved for any reason, OnLeaderboardsRetrieveFailure() is fired and we set LeaderboardsRetrieveListener.retrieved to false.

Either way, we use LeaderboardsRetrieveListener.retrieved later to ensure that the leaderboards definitions are retrieved.

LeaderboardEntriesRetrieveListener

    private class LeaderboardEntriesRetrieveListener : GlobalLeaderboardEntriesRetrieveListener
    {
        public override void OnLeaderboardEntriesRetrieveSuccess(string leaderboardName, uint entryCount)
        {
            Debug.Log("Leaderboard \"" + leaderboardName + "\" entries retrieved\nEntry count: " + entryCount);

            leaderboardEntries.Clear();
            leaderboardEntries.TrimExcess();

            for (uint i = 0; i < entryCount; i++)
            {
                GalaxyID userID = new GalaxyID();
                uint rank = 0;
                int score = 0;
                string username = null;
                object[] entryDetails = new object[] { rank, score, username };

                GalaxyInstance.Stats().GetRequestedLeaderboardEntry(i, ref rank, ref score, ref userID);
                username = GalaxyManager.Instance.Friends.GetFriendPersonaName(userID);
                entryDetails[0] = rank;
                entryDetails[1] = score; 
                entryDetails[2] = username;
                Debug.Log("Created object #" + i + " | " + rank + " | " + score + " | " + username);
                leaderboardEntries.Add(entryDetails);
            }

            if (GameObject.Find("LeaderboardsScreen")) GameObject.Find("LeaderboardsScreen").GetComponent<LeaderboardsController>().DisplayLeaderboard();

        }

        public override void OnLeaderboardEntriesRetrieveFailure(string leaderboardName, FailureReason failureReason)
        {
            Debug.LogWarning("Could not retrieve leaderboard \"" + leaderboardName + "\" entries for reason: " + failureReason);
            if (GameObject.Find("LeaderboardsScreen"))
            {
                if (failureReason == FailureReason.FAILURE_REASON_NOT_FOUND) GameObject.Find("LeaderboardsScreen").GetComponent<LeaderboardsController>().DisplayMessage("No entry for the current user in selected leadeboard");
                if (failureReason == FailureReason.FAILURE_REASON_UNDEFINED) GameObject.Find("LeaderboardsScreen").GetComponent<LeaderboardsController>().DisplayMessage("Failure reason undefined");
            }
        }
    }

This listener callbacks are fired when entries for a specific leaderboard have been retrieved. To request leaderboard entries, you can call:

In our project, we only use the first two methods. No matter which method is used inside the LeaderboardEntriesRetrieveListener.OnLeaderboardEntriesRetrieveSuccess(string leaderboardName, uint entryCount), we define the following local variables:

Variable Description
uint rank Used as a reference for the currently processed user’s rank later in the method
int score Used as a reference for the currently processed user’s score later in the method
GalaxyID userID Used as a reference for the currently processed user’s GalaxyID later in the method
string username Used as a reference for the currently processed user’s name later in the method

First, we make sure that Leaderboards.leaderboardEntries is empty by calling leaderboardEntries.Clear() and leaderboardEntries.TrimExcess().

Next, we use a for loop to iterate through all entries in the leaderboard table (each entry represents a score of one user). Inside this loop we:

  1. Initialize the userID variable and define the rank, score and username variables.
  2. Create a new object array for the entry.
  3. Retrieve data for each entry separately with the for loop index using the GalaxyInstance.Stats().GetRequestedLeaderboardEntry(uint i, uint ref rank, int ref score, GalaxyID ref userID) method.
  4. Add the created object array to the Leaderboards.leaderboardEntries list.

Once the Leaderboards.leaderboardEntries list is ready, we display the list using the LeaderboardsController.DisplayLeaderboard() method. Note that we first check if the LeaderboardsScreen GameObject is enabled.

If leaderboard entries retrieval failed for any reason, we display a message informing the user that the leaderboards couldn’t be retrieved.

LeaderboardScoreUpdateListener

    private class LeaderboardScoreUpdateListener : GlobalLeaderboardScoreUpdateListener
    {
        public override void OnLeaderboardScoreUpdateSuccess(string leaderboardName, int score, uint oldRank, uint newRank)
        {
            Debug.Log("Set leaderboard \"" + leaderboardName + "\" score to " + score);
        }
        public override void OnLeaderboardScoreUpdateFailure(string leaderboardName, int score, FailureReason failureReason)
        {
            Debug.LogWarning("Could not set leaderboard \"" + leaderboardName + "\" entry for reason: " + failureReason);
        }
    }

This listener fires when a user leaderboard score was updated. We use it for debug purposes only as we don’t want to show this information to the player.