Achievements - StansAssets/com.stansassets.android-native GitHub Wiki

Achievements can be a great way to increase your users' engagement within your game. You can implement achievements in your game to encourage players to experiment with features they might not normally use, or to approach your game with entirely different play styles. Achievements can also be a fun way for players to compare their progress with each other and engage in light-hearted competition.

If you haven't already done so, you might find it helpful to review the achievements game concepts.

To start using the achievements API, your game must first obtain an AN_AchievementsClient object. You can do this by calling the Games.GetAchievementClient() method.

Unlocking achievements

To unlock an achievement, call the AN_AchievementsClient.Unlock() method and pass in the achievement ID. The following code snippet shows how your app can unlock achievements:

using SA.Android.GMS.Games;
...

string achievementId = "YOUR_AchievementId_HERE";
var client = AN_Games.GetAchievementsClient();
client.Unlock(achievementId);

If the achievement is of the incremental type (that is, several steps are required to unlock it), call AN_AchievementsClient.Increment() instead. The following code snippet shows how your app can increment the player’s achievement:

using SA.Android.GMS.Games;
...

int numSteps = 1;
string achievementId = "YOUR_AchievementId_HERE";
var client = AN_Games.GetAchievementsClient();
client.Increment(achievementId, numSteps);

You do not need to write additional code to unlock the achievement; Google Play games services automatically unlocks the achievement once it reaches its required number of steps.

When making calls to update and load achievements, make sure to also follow these best practices to avoid exceeding your API quota.

Immediate Operations

As an alternative to the following methods:

  • Reveal
  • Unlock
  • Increment

You may use the Immediate analogs:

  • RevealImmediate
  • UnlockImmediate
  • IncrementImmediate

The main difference is that this form of the API will attempt to update the user's achievement on the server immediately. And you will be able to pass the callback that gets's called once the server has been updated. See the example bellow:

using SA.Android.GMS.Games;
...

string achievementId = "YOUR_AchievementId_HERE";
client.RevealImmediate(achievementId, (result) => {
    Debug.Log($"Operation Succeeded: {result.IsSucceeded}");
});

Displaying achievements

To show a player's achievements, call AN_AchievementsClient.GetAchievementsIntent() to get an AN_Intent to create the default achievements user interface. Your game can then bring up the UI by calling StartActivityForResult. The following code snippet shows how your app can display the default achievement user interface.

using SA.Android.App;
using SA.Android.GMS.Games;
...

var client = AN_Games.GetAchievementsClient();
client.GetAchievementsIntent(result => {
    if(result.IsSucceeded) {
        var intent = result.Intent;
        var proxy = new AN_ProxyActivity();
        proxy.StartActivityForResult(intent, intentResult => {
            proxy.Finish();
             //TODO you might want to check is user had sigend out with that UI
        });
    } else {
         Debug.LogError($"Failed to Get Achievements Intent {result.Error.FullMessage}");
    }
});

An example of the default achievements UI is shown below.

Achievements

Creating In-Game achievements UI

If instead of using the default Google Play UI, you would like to build your own achievements in-game UI, you can load the achievements metadata. See the snippet below:

var client = AN_Games.GetAchievementsClient();
client.Load(false, result => {
    if (result.IsSucceeded) {
        Debug.Log($"Load Achievements Succeeded, count: {result.Achievements.Count}");
        foreach (var achievement in result.Achievements) {
            Debug.Log("------------------------------------------------");
            Debug.Log($"achievement.AchievementId: {achievement.AchievementId}");
            Debug.Log($"achievement.Description: {achievement.Description}");
            Debug.Log($"achievement.Name: {achievement.Name}");
            Debug.Log($"achievement.UnlockedImageUri: {achievement.UnlockedImageUri}");
            Debug.Log($"achievement.CurrentSteps: {achievement.CurrentSteps}");
            Debug.Log($"achievement.TotalSteps: {achievement.TotalSteps}");
            Debug.Log($"achievement.Type: {achievement.Type}");
            Debug.Log($"achievement.Sate: {achievement.State}");
        }
        Debug.Log("------------------------------------------------");
    }
    else {
        Debug.LogError($"Load Achievements Failed: {result.Error.FullMessage}");
    }
    foreach (var achievement in result.Achievements) {
        if(achievement.Type == AN_Achievement.AchievementType.INCREMENTAL) {
            client.Increment(achievement.AchievementId, 1);
            continue;
        }
        if (achievement.State == AN_Achievement.AchievementState.HIDDEN) {
             client.Reveal(achievement.AchievementId);
             continue;
        }
        if (achievement.State != AN_Achievement.AchievementState.UNLOCKED) {
             client.Unlock(achievement.AchievementId);
        }
    }
});

AchievementState

public enum UM_AchievementState {
    /// <summary>
    /// Achievement is unlocked.
    /// </summary>
    UNLOCKED = 0,

    /// <summary>
    /// Achievement is revealed.
    /// </summary>
    REVEALED = 1,

    /// <summary>
    /// Achievement is hidden.
    /// </summary>
    HIDDEN = 2
}

AchievementType

public enum UM_AchievementType {
    /// <summary>
    /// Standard Achievement.
    /// </summary>
    STANDARD = 0,

    /// <summary>
    /// Incremental Achievement.
    /// </summary>
    INCREMENTAL = 1
}

As you may notice the AN_Achievement object contains UnlockedImageUri property. The URL will be formatted similarly to the example below:

content://com.google.android.gms.games.background/images/b4d1b8fd/2956

This means you can't use UnityWebRequest to download the image using this URL. Since google play stores all the images locally. In order to obtain an image that you can use in your game, you need to use Image Manager.

⚠️ **GitHub.com Fallback** ⚠️