Apple Game Center

Minimum SDK version: 2.4.0

This article guides you through the following scenarios in setting up authentication for players in your game with an Apple Game Center player identifier:

  • Set up an Apple Game Center sign-in
  • Sign in a returning user or create a new user.
  • Update a user from an anonymous sign-in to a platform sign-in via an Apple Game Center account.

Attention: The following concerns products or services (each a “Third Party Product”) that are not developed, owned, or operated by Unity. This information might not be up-to-date or complete, and is provided to you for your information and convenience only. Your access and use of any Third Party Product is governed solely by the terms and conditions of such Third Party Product. Unity makes no express or implied representations or warranties regarding such Third Party Products, and will not be responsible or liable, directly or indirectly, for any actual or alleged damage or loss arising from your use thereof (including damage or loss arising from any content, advertising, products or other materials on or available from the provider of any Third Party Products).

To provide an Apple Game Center sign-in option for the players in your game, set up your app to enable sign-in with Apple Game Center.

You can add Apple Game Center either in the Unity Editor directly, or in the Unity Cloud Dashboard.

Set up an Apple Game Center sign-in

  1. Set up and install the Apple Game Kit Unity plugin, found in the Apple Unity Plug-ins repository. The GameKit framework is used to implement Apple Game Center features including player identity.

  2. Add Apple Game Center as an ID provider for Unity:

    1. In the Unity Editor menu, go to Edit > Project Settings…, then select Services > Authentication from the navigation menu.
    2. Set ID Providers to Apple Game Center, then select Add.
    3. Enter the Bundle ID from the Apple developer console in the Bundle ID text field, then select Save. The Bundle ID should look like this: "com.something.somethingelse".

Important: For Unity Authentication, the timestamp input is only valid for 10 minutes for security reasons. Before calling SignInWithAppleGameCenterAsync or LinkWithAppleGameCenterAsync, please call Apple's FetchItems API to receive fresh inputs. After a single successful call to SignInWithAppleGameCenterAsync or LinkWithAppleGameCenterAsync, there is no need to call these APIs anymore.

After installing the required plugin and setting up the ID provider, you can use the following sample code to retrieve the parameters for identity verification:

using System;
using System.Threading.Tasks;
using UnityEngine;
using Apple.GameKit;

public class AppleGameCenterExampleScript : MonoBehaviour
{
    string Signature;
    string TeamPlayerID;
    string Salt;
    string PublicKeyUrl;
    string Timestamp;

    // Start is called before the first frame update
    async void Start()
    {
        await Login();
    }

    public async Task Login()
    {
        if (!GKLocalPlayer.Local.IsAuthenticated)
        {
            // Perform the authentication.
            var player = await GKLocalPlayer.Authenticate();
            Debug.Log($"GameKit Authentication: player {player}");

            // Grab the display name.
            var localPlayer = GKLocalPlayer.Local;
            Debug.Log($"Local Player: {localPlayer.DisplayName}");

            // Fetch the items.
            var fetchItemsResponse =  await GKLocalPlayer.Local.FetchItems();

            Signature = Convert.ToBase64String(fetchItemsResponse.GetSignature());
            TeamPlayerID = localPlayer.TeamPlayerId;
            Debug.Log($"Team Player ID: {TeamPlayerID}");

            Salt = Convert.ToBase64String(fetchItemsResponse.GetSalt());
            PublicKeyUrl = fetchItemsResponse.PublicKeyUrl;
            Timestamp = fetchItemsResponse.Timestamp.ToString();

            Debug.Log($"GameKit Authentication: signature => {Signature}");
            Debug.Log($"GameKit Authentication: publickeyurl => {PublicKeyUrl}");
            Debug.Log($"GameKit Authentication: salt => {Salt}");
            Debug.Log($"GameKit Authentication: Timestamp => {Timestamp}");
        }
        else
        {
            Debug.Log("AppleGameCenter player already logged in.");
        }
    }
}

If you see an error related to MissingMethodException from within the Apple.GameKit namespace, it is likely due to relevant code being stripped during compilation. That can be addressed by using Link XML to ensure the offending code is preserved. Alternatively the code stripping option in Player Settings can be set to "Minimal" which may resolve the issue, but be aware that this may increase the size of the final binary.

Sign in a returning player or create new player

You can use the SignInWithAppleGameCenterAsync method to either:

  • Create a new Unity Authentication player with the Apple Game Center credentials.
  • Sign in an existing player using the Apple Game Center credentials.

If no Unity Authentication player in your project is associated with the credentials, SignInWithAppleGameCenterAsync creates a new player. If a Unity Authentication player in your project is associated with the credentials, SignInWithAppleCenterAsync signs into that player's account. This function doesn't consider the cached player, and SignInWithAppleGameCenterAsync replaces the cached player.

async Task SignInWithAppleGameCenterAsync(string signature, string teamPlayerId, string   publicKeyURL, string salt, ulong timestamp)
{
    try
    {
        await AuthenticationService.Instance.SignInWithAppleGameCenterAsync(signature, teamPlayerId, publicKeyURL, salt, timestamp);
        Debug.Log("SignIn is successful.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}

For more information about cached players, refer to Sign In a Cached Player.

Updating a player from anonymous to an Apple Game Center account

After you’ve set up anonymous authentication, if the player wants to upgrade from being anonymous to creating an Apple Game Center account and sign in using Apple Game Center, your game should prompt the player to trigger the Apple Game Center sign-in and get the ID verification parameters from GameKit. Then, call the LinkWithAppleGameCenterAsync API to link the player to the Apple Game Center teamPlayerID.

If a cached player exists on the SDK, you can link the cached player to the Apple Game Center Account.

  1. Sign into the cached player's account using SignInAnonymouslyAsync.
  2. Link the cached player's account to the Apple account with LinkWithAppleGameCenterAsync.

For more information about cached players, refer to Sign In a Cached Player.

async Task LinkWithAppleGameCenterAsync(string signature, string teamPlayerId, string   publicKeyURL, string salt, ulong timestamp)
{
    try
    {
        await AuthenticationService.Instance.LinkWithAppleGameCenterAsync(signature, teamPlayerId, publicKeyURL, salt, timestamp);
        Debug.Log("Link is successful.");
    }
    catch (AuthenticationException ex) when (ex.ErrorCode == AuthenticationErrorCodes.AccountAlreadyLinked)
    {
        // Prompt the player with an error message.
        Debug.LogError("This user is already linked with another account. Log in instead.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}

Use the UnlinkAppleGameCenterAsync API so your players can unlink their Apple Game Center account. Once unlinked, if their account isn’t linked to any additional identity, it transitions to an anonymous account.

async Task UnlinkAppleGameCenterAsync()
{
   try
   {
       await AuthenticationService.Instance.UnlinkAppleGameCenterAsync();
       Debug.Log("Unlink is successful.");
   }
   catch (AuthenticationException ex)
   {
       // Compare error code to AuthenticationErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
   catch (RequestFailedException ex)
   {
       // Compare error code to CommonErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
}