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.
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.
privatevoidOnEnable(){ // register for eventsGameServices.OnAuthStatusChange+= OnAuthStatusChange;}privatevoidOnDisable(){ base.OnDisable(); // unregister from eventsGameServices.OnAuthStatusChange-= OnAuthStatusChange;}
Check Availability
First thing, we need to do is to check if game services are enabled in settings. If available we can proceed with sign in.
bool isAvailable =GameServices.IsAvailable();
This returns true if feature is enabled in essential kit settings.
Authenticate Player
If service is available, we can move on to Authenticating user.
GameServices.Authenticate();
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.
You can access ILocalUser Instance any time through GameServices. However, you will get it null if the authentication is not successful.
ILocalPlayer localPlayer =GameServices.LocalUser;
Incase if you want to know if the player is authenticated or not, you can check with IsAuthenticated
bool loggedIn =GameServices.IsAuthenticated
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.
GameServices.LoadAchievementDescriptions((result, error) =>{if (error ==null) {IAchievementDescription[] descriptions =result.AchievementDescriptions;Debug.Log("Request to load achievement descriptions finished successfully.");Debug.Log("Total achievement descriptions fetched: "+descriptions.Length);Debug.Log("Below are the available achievement descriptions:");for (int iter =0; iter <descriptions.Length; iter++) {IAchievementDescription description1 =descriptions[iter];Debug.Log(string.Format("[{0}]: {1}", iter, description1)); } }else {Debug.Log("Request to load achievement descriptions failed with error. Error: "+ error); }});
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.
GameServices.LoadAchievements((result, error) =>{if (error ==null) { // show console messagesIAchievement[] achievements =result.Achievements;Debug.Log("Request to load achievements finished successfully.");Debug.Log("Total achievements fetched: "+achievements.Length);Debug.Log("Below are the available achievements:");for (int iter =0; iter <achievements.Length; iter++) {IAchievement achievement1 =achievements[iter];Debug.Log(string.Format("[{0}]: {1}", iter, achievement1)); } }else {Debug.Log("Request to load achievements failed with error. Error: "+ error); }});
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 a one-shot Achivement (This reveals and unlocks an achievemet)
string achievementId; //This is the Id set in Setup for each achievementdouble percentageCompleted =100;// This is in the range [0 - 100]GameServices.ReportAchievementProgress(achievementId, percentageCompleted, (success, error) =>{if (success) {Debug.Log("Request to submit progress finished successfully."); }else {Debug.Log("Request to submit progress failed with error. Error: "+ error); }});
Report with 0 progress value if you just want to reveal a hidden achievement!
Report an incremental Achivement
string achievementId; //This is the Id set in Setup for each achievementint stepsCompleted =4; //Steps completed by user until nowint totalSteps =10; //This value you can get from AchievementDescription (NumberOfStepsRequiredToUnlockAchievement)double percentageCompleted = (stepsCompleted/(totalSteps *1.0)) *100.0;// This is in the range [0 - 100]GameServices.ReportAchievementProgress(achievementId, percentageCompleted, (error) =>{if (error ==null) {Debug.Log("Request to submit progress finished successfully."); }else {Debug.Log("Request to submit progress failed with error. Error: "+ error); }});
You can get the achievement description instance from LoadAchievementDescriptions callback method.
IAchievementDescription achievementDescription; //This is the Id set in Setup for each achievementdouble percentageCompleted =100;// This is in the range [0 - 100]GameServices.ReportAchievementProgress(achievementDescription, percentageCompleted, (success, error) =>{if (success) {Debug.Log("Request to submit progress finished successfully."); }else {Debug.Log("Request to submit progress failed with error. Error: "+ error); }});
You can get the achievement description instance from LoadAchievement callback method.
IAchievement achievement; //This is the Id set in Setup for each achievementdouble percentageCompleted =100;// This is in the range [0 - 100]GameServices.ReportAchievementProgress(achievement, percentageCompleted, (success, error) =>{if (error ==null) {Debug.Log("Request to submit progress finished successfully."); }else {Debug.Log("Request to submit progress failed with error. Error: "+ error); }});
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.
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.
GameServices.LoadLeaderboards((result, error) =>{if (error ==null) { // show console messagesILeaderboard[] leaderboards =result.Leaderboards;Debug.Log("Request to load leaderboards finished successfully.");Debug.Log("Total leaderboards fetched: "+leaderboards.Length);Debug.Log("Below are the available leaderboards:");for (int iter =0; iter <leaderboards.Length; iter++) {ILeaderboard leaderboard1 =leaderboards[iter];Debug.Log(string.Format("[{0}]: {1}", iter, leaderboard1)); } }else {Debug.Log("Request to load leaderboards failed with error. Error: "+ error); }});
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.
string leaderboardId; // This is the Id you set in Essential Kit Settings for the leaderboard entryILeaderboard leaderboard =GameServices.CreateLeaderboard(leaderboardId);
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.
leaderboard.LoadScoresQuerySize=10; //leaderboard is ILeaderboard instance
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.
leaderboard.TimeScope=LeaderboardTimeScope.Week;// For fetching submitted scores past week.
Loading Top Scores
leaderboard.LoadTopScores((result, error) => {if (error ==null) {Debug.Log("Scores loaded : "+result.Scores);for (int iter =0; iter <result.Scores.Length; iter++) {IScore score =result.Scores[iter];Debug.Log(string.Format("Player {0} Rank : {1} Score : {2}",score.Player.DisplayName,score.Rank,score.Value); } } else {Debug.LogError("Failed loading top scores with error : "+error.Description); }});
Loading Player centered scores
leaderboard.LoadPlayerCenteredScores((result, error) => {if (error ==null) {Debug.Log("Scores loaded : "+result.Scores);for (int iter =0; iter <result.Scores.Length; iter++) {IScore score =result.Scores[iter];Debug.Log(string.Format("Player {0} Rank : {1} Score : {2}",score.Player.DisplayName,score.Rank,score.Value); } } else {Debug.LogError("Failed loading top scores with error : "+error.Description); }});
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.
long score =57;string leaderboardId ="leaderboardId";// Value from setup done in inspectorstring tag ="weapon-6"; //This must be a 8 length ascii chars - OptionalGameServices.ReportScore(leaderboardId, score, (success, error) =>{if (success) {Debug.Log("Request to submit score finished successfully."); }else {Debug.Log("Request to submit score failed with error: "+error.Description); }}, tag);
Reporting with leaderboard id
long score =57;ILeaderboard leaderboardInstance;// This you can get from either LoadLeaderboards or CreateLeaderboardstring tag ="weapon-6"; //This must be a 8 length ascii charsGameServices.ReportScore(leaderboardInstance, score, (success, error) =>{if (success) {Debug.Log("Request to submit score finished successfully."); }else {Debug.Log("Request to submit score failed with error: "+error.Description); }}, tag);
NEW : Helps in Game Retention and Monetization
Now you can submit a tag to a score to give some context which can be retrieved back when fetching leaderboards. With this you can do something like below
Show a popup to purchase an in-app item used to secure the score
Showcase player's past score and how he/she improved
Show level in which player reached this score
Show Leaderboards
By default, native platforms provide a way to show the leaderboards with their own UI.
string leaderboardId ="leaderboardId";// Id you set for settings in Essential Kit SettingsGameServices.ShowLeaderboard(leaderboardId,LeaderboardTimeScope.AllTime, callback: (result, error) =>{Debug.Log("Leaderboard UI closed");});