Usage
Once you are done with setup by configuring leaderboards and achievements, you can start implementing the feature with GameServices class and you can use this by importing the namespace.
1
using VoxelBusters.CoreLibrary;
2
using VoxelBusters.EssentialKit;
Copied!

Overview

For accessing and managing leaderboards, achievements we need to let user authenticate first. Once user tries to login, the status updates will be posted in the form of events (OnAuthStatusChange).
Have the list of leaderboard and achievement id's ready (you set in setup) as these are required to refer them from code.
For submitting a score, you can either create a Leaderboard instance or use utility method of GameServices.
For reporting progress, create an achievement instance or use utility method of Game Services.

Register for Events

You need to register for GameServices.OnAuthStatusChange event for getting the updates on auth status once you attempt logging in.
1
private void OnEnable()
2
{
3
// register for events
4
GameServices.OnAuthStatusChange += OnAuthStatusChange;
5
}
6
7
private void OnDisable()
8
{
9
base.OnDisable();
10
11
// unregister from events
12
GameServices.OnAuthStatusChange -= OnAuthStatusChange;
13
}
Copied!

Check Availability

First thing, we need to do is to check if game services are supported on running platform. If available we can proceed with sign in.
1
bool isAvailable = GameServices.IsAvailable();
Copied!
This returns true if service is supported on the platform where application is running, false otherwise.

Authenticate Player

If service is available, we can move on to Authenticating user.
1
GameServices.Authenticate();
Copied!
Authenticate method may open a dialog to let user enter the credentials for logging in.

On iOS, it may open Game Center login dialog and on Android, it can open a dialog for Game Play Services login.

On Android, we try first with the silent login and if it fails, it opens a login dialog. If silent login is successful, it won't show up any login dialog.
You can listen to the status of the login through the event GameServices.OnAuthStatusChange and on successful login, you get an instance of ILocalPlayer or an error on failure.
1
private void OnAuthStatusChange(GameServicesAuthStatusChangeResult result, Error error)
2
{
3
if(error == null)
4
{
5
Debug.Log("Received auth status change event");
6
Debug.Log("Auth status: " + result.AuthStatus);
7
8
if(result.AuthStatus == LocalPlayerAuthStatus.Authenticated)
9
Debug.Log("Local player: " + result.LocalPlayer);
10
11
}
12
else
13
{
14
Debug.LogError("Failed login with error : " + error);
15
}
16
}
Copied!
You can access ILocalUser Instance any time through GameServices. However, you will get it null if the authentication is not successful.
1
ILocalPlayer localPlayer = GameServices.LocalUser;
Copied!
Incase if you want to know if the player is authenticated or not, you can check with IsAuthenticated
1
bool loggedIn = GameServices.IsAuthenticated
Copied!
Game Center login view for iOS
Google Play Services login view for Android

Achievements

Achievements can be a great way to increase your users' engagement within your game. Achievements can also be a fun way for players to compare their progress with each other and engage in light-hearted competition.

Get all Achievement Details

If you are planning for having your own custom achievements UI, you can get details of all achievements with LoadAchievementDescriptions call.
1
GameServices.LoadAchievementDescriptions((result, error) =>
2
{
3
if (error == null)
4
{
5
IAchievementDescription[] descriptions = result.AchievementDescriptions;
6
Debug.Log("Request to load achievement descriptions finished successfully.");
7
Debug.Log("Total achievement descriptions fetched: " + descriptions.Length);
8
Debug.Log("Below are the available achievement descriptions:");
9
for (int iter = 0; iter < descriptions.Length; iter++)
10
{
11
IAchievementDescription description1 = descriptions[iter];
12
Debug.Log(string.Format("[{0}]: {1}", iter, description1));
13
}
14
}
15
else
16
{
17
Debug.Log("Request to load achievement descriptions failed with error. Error: " + error);
18
}
19
});
Copied!
Achievement Description : This holds description and images used to describe an achievement.

Get achievements reported

You can get the list of achievements which got reported till date with LoadAchievements.
1
GameServices.LoadAchievements((result, error) =>
2
{
3
if (error == null)
4
{
5
// show console messages
6
IAchievement[] achievements = result.Achievements;
7
Debug.Log("Request to load achievements finished successfully.");
8
Debug.Log("Total achievements fetched: " + achievements.Length);
9
Debug.Log("Below are the available achievements:");
10
for (int iter = 0; iter < achievements.Length; iter++)
11
{
12
IAchievement achievement1 = achievements[iter];
13
Debug.Log(string.Format("[{0}]: {1}", iter, achievement1));
14
}
15
}
16
else
17
{
18
Debug.Log("Request to load achievements failed with error. Error: " + error);
19
}
20
});
Copied!
Difference between LoadAchievementDescriptions and LoadAchievements is the later only returns the achievements which are reported with progress (check ReportProgress below). Where as LoadAchievementDescriptions returns all the available achievements created on store dashboards.

Report Achievement Progress

Achievement Progress denotes how much part of achievement is achieved.
    100 % progress denotes Achievement is Unlocked and revealed to the player.
    One shot/Instant achievements unlock instantly and needs to be set 100% while reporting.
    Incremental achievements (which takes many steps to get unlocked) can be set with 0-100% range based on steps completed by the player.
Report With Achievement Id
Report with Achievement Description Instance
Report with Achievement Instance
Report a one-shot Achivement (This reveals and unlocks an achievemet)
1
string achievementId; //This is the Id set in Setup for each achievement
2
double percentageCompleted = 100;// This is in the range [0 - 100]
3
GameServices.ReportAchievementProgress(achievementId, percentageCompleted, (error) =>
4
{
5
if (error == null)
6
{
7
Debug.Log("Request to submit progress finished successfully.");
8
}
9
else
10
{
11
Debug.Log("Request to submit progress failed with error. Error: " + error);
12
}
13
});
Copied!
Report with 0 progress value if you just want to reveal a hidden achievement!
Report an incremental Achivement
1
string achievementId; //This is the Id set in Setup for each achievement
2
int stepsCompleted = 4; //Steps completed by user until now
3
int totalSteps = 10; //This value you can get from AchievementDescription (NumberOfStepsRequiredToUnlockAchievement)
4
double percentageCompleted = stepsCompleted/(totalSteps * 1.0);// This is in the range [0 - 100]
5
GameServices.ReportAchievementProgress(achievementId, percentageCompleted, (error) =>
6
{
7
if (error == null)
8
{
9
Debug.Log("Request to submit progress finished successfully.");
10
}
11
else
12
{
13
Debug.Log("Request to submit progress failed with error. Error: " + error);
14
}
15
});
Copied!
You can get the achievement description instance from LoadAchievementDescriptions callback method.
1
IAchievementDescription achievementDescription; //This is the Id set in Setup for each achievement
2
double percentageCompleted = 100;// This is in the range [0 - 100]
3
GameServices.ReportAchievementProgress(achievementDescription, percentageCompleted, (error) =>
4
{
5
if (error == null)
6
{
7
Debug.Log("Request to submit progress finished successfully.");
8
}
9
else
10
{
11
Debug.Log("Request to submit progress failed with error. Error: " + error);
12
}
13
});
Copied!
You can get the achievement description instance from LoadAchievement callback method.
1
IAchievement achievement; //This is the Id set in Setup for each achievement
2
double percentageCompleted = 100;// This is in the range [0 - 100]
3
GameServices.ReportAchievementProgress(achievement, percentageCompleted, (error) =>
4
{
5
if (error == null)
6
{
7
Debug.Log("Request to submit progress finished successfully.");
8
}
9
else
10
{
11
Debug.Log("Request to submit progress failed with error. Error: " + error);
12
}
13
});
Copied!

Show Achievements

You can display the default UI provided by native platform. If you are looking for displaying your own UI, you can make use of details form Achievements and Achievement Descriptions.
1
GameServices.ShowAchievements((result, error) =>
2
{
3
Debug.Log("Achievements view closed");
4
});
Copied!

Leaderboards

Leaderboards let your players to compete socially by sharing their scores to the world. Three actions can be done from Leaderboards API.
    Load details of Leaderboards
    Loading Scores from a leaderboard(can give a User Scope and Time Scope).
    Reporting score to a leaderboard
    Show Leaderboards

Load details of Leaderboards

If you want to display the list of leaderboards configured on native platforms (Game Center and Google Play Services), you can get all the available leaderboards with LoadLeaderboards. This returns a list of ILeaderboard(doc) which has details regarding title, local player score and option to load icon image set for the leaderboard etc.
1
GameServices.LoadLeaderboards((result, error) =>
2
{
3
if (error == null)
4
{
5
// show console messages
6
ILeaderboard[] leaderboards = result.Leaderboards;
7
Debug.Log("Request to load leaderboards finished successfully.");
8
Debug.Log("Total leaderboards fetched: " + leaderboards.Length);
9
Debug.Log("Below are the available leaderboards:");
10
for (int iter = 0; iter < leaderboards.Length; iter++)
11
{
12
ILeaderboard leaderboard1 = leaderboards[iter];
13
Debug.Log(string.Format("[{0}]: {1}", iter, leaderboard1));
14
}
15
}
16
else
17
{
18
Debug.Log("Request to load leaderboards failed with error. Error: " + error);
19
}
20
});
Copied!

Load Scores of a Leaderboard

Scores submitted to a leaderboard can be fetched with ILeaderboard instance.
You can get ILeaderboard instance either by calling LoadLeaderboards or by creating an instance of Leaderboard.
1
string leaderboardId; // This is the Id you set in Essential Kit Settings for the leaderboard entry
2
ILeaderboard leaderboard = GameServices.CreateLeaderboard(leaderboardId);
Copied!
Now you have an instance of ILeaderboard.
Leaderboards data will be fetched in terms of pages. This is because there can be lot of results reported by many and pagination will help not to load complete data at once.
You can set max scores that needs to be fetched by setting LoadScoresQuerySize property of ILeaderboard.
1
leaderboard.LoadScoresQuerySize = 10; //leaderboard is ILeaderboard instance
Copied!
Scores query size has a limit on Android where it caps to max of 25 scores.
You can set time scope to the scores that needs to be fetched. Time scope defines the time when the scores were submitted. This can be any of Today/Week/AllTime.
1
leaderboard.TimeScope = LeaderboardTimeScope.Week;// For fetching submitted scores past week.
Copied!

Loading Top Scores

1
leaderboard.LoadTopScores((result, error) => {
2
if (error == null)
3
{
4
Debug.Log("Scores loaded : " + result.Scores);
5
for (int iter = 0; iter < result.Scores.Length; iter++)
6
{
7
IScore score = result.Scores[iter];
8
Debug.Log(string.Format("Player {0} Rank : {1} Score : {2}", score.Player.DisplayName, score.Rank, score.Value);
9
}
10
}
11
else
12
{
13
Debug.LogError("Failed loading top scores with error : ", error.Description);
14
}
15
});
Copied!

Loading Player centered scores

1
leaderboard.LoadPlayerCenteredScores((result, error) => {
2
if (error == null)
3
{
4
Debug.Log("Scores loaded : " + result.Scores);
5
for (int iter = 0; iter < result.Scores.Length; iter++)
6
{
7
IScore score = result.Scores[iter];
8
Debug.Log(string.Format("Player {0} Rank : {1} Score : {2}", score.Player.DisplayName, score.Rank, score.Value);
9
}
10
}
11
else
12
{
13
Debug.LogError("Failed loading top scores with error : ", error.Description);
14
}
15
});
Copied!
As the results returned by LoadTopScores and LoadPlayerCenteredScores are limited by LoadScoresQuerySize value, you can fetch the rest of the pages with LoadPrevious and LoadNext methods.

Report Score to a leaderboard

For reporting a score to leaderboard, you need to have a ILeaderboard(doc) instance or Id of the leaderboard set in Essential Kit Settings or an IScore(doc) instance created from CreateScore.
There are multiple ways to report a score
With Leaderboard Id
With ILeaderboard instance
With IScore instance
1
long score = 57;
2
string leaderboardId = "leaderboardId";// Value from setup done in inspector
3
GameServices.ReportScore(leaderboardId, score, (error) =>
4
{
5
if (error == null)
6
{
7
Debug.Log("Request to submit score finished successfully.");
8
}
9
else
10
{
11
Debug.Log("Request to submit score failed with error: " + error.Description);
12
}
13
});
Copied!
Reporting with leaderboard id
1
long score = 57;
2
ILeaderboard leaderboardInstance;// This you can get from either LoadLeaderboards or CreateLeaderboard
3
GameServices.ReportScore(leaderboardInstance, score, (error) =>
4
{
5
if (error == null)
6
{
7
Debug.Log("Request to submit score finished successfully.");
8
}
9
else
10
{
11
Debug.Log("Request to submit score failed with error: " + error.Description);
12
}
13
});
Copied!
Reporting with IScore instance
1
long score = 57;
2
string leaderboardId = "leaderboardId";// Value from setup done in inspector
3
IScore scoreInstance = GameServices.CreateScore(leaderboardId);
4
scoreInstance.ReportScore((error) =>
5
{
6
if (error == null)
7
{
8
Debug.Log("Request to submit score finished successfully.");
9
}
10
else
11
{
12
Debug.Log("Request to submit score failed with error: " + error.Description);
13
}
14
});
Copied!

Show Leaderboards

By default, native platforms provide a way to show the leaderboards with their own UI.

Showing All Leaderboards

1
GameServices.ShowLeaderboards(callback: (result, error) =>
2
{
3
Debug.Log("Leaderboards UI closed");
4
});
Copied!

Showing a specific Leaderboard with Time Scope

1
string leaderboardId = "leaderboardId";// Id you set for settings in Essential Kit Settings
2
GameServices.ShowLeaderboard(leaderboardId, LeaderboardTimeScope.AllTime, callback: (result, error) =>
3
{
4
Debug.Log("Leaderboard UI closed");
5
});
Copied!
Last modified 5d ago