# Apple Game Center

> Provide an Apple Game Center sign-in option to enable players to authenticate using their Game Center accounts on Apple platforms.

###### 最小 SDK バージョン: 2.4.0##minimum-sdk-version-240

このセクションでは、Apple Game Center のプレイヤー ID を使用してゲーム内でのプレイヤーの認証を設定する以下のシナリオについて説明します。

* Apple Game Center サインインの設定
* 戻ってきたプレイヤーをサインインする、または新しいプレイヤーを作成する。
* プレイヤーを匿名ログインから Apple Game Center アカウントを介したプラットフォームログインへと更新する。

ゲーム内のプレイヤーに Apple Game Center サインインのオプションを提供するには、アプリケーションを設定して Apple Game Center でのサインインを有効にしてください。

Apple Game Center は、Unity エディター内で直接追加するか、[Unity Dashboard](https://cloud.unity.com/) で追加できます。

## Apple Game Center サインインの設定

1. Apple Game Kit Unity プラグインを設定してインストールします (これは、[Apple Unity Plug-ins](https://github.com/apple/unityplugins) リポジトリにあります)。[GameKit](https://developer.apple.com/documentation/gamekit) フレームワークは、プレイヤー識別を含む Apple Game Center の機能を実装するために使用されます。

2. Apple Game Center を Unity 用の ID プロバイダーとして追加します。

   1. Unity エディターメニューで、**Edit** (編集) > **Project Settings...** (プロジェクト設定...) を選択し、ナビゲーションメニューから **Services** (サービス) > **Authentication** を選択します。
   2. **ID Providers** (ID プロバイダー) を **Apple Game Center** に設定し、**Add** (追加) を選択します。
   3. Apple 開発者コンソールからの **バンドル ID** を **Bundle ID** (バンドル ID) テキストフィールドに入力し、**Save** (保存) を選択します。バンドル ID は次のようになります: "**com.something.somethingelse**"。

ノート: 参照先のパッケージは、Unity によって開発、所有、運営されているものではありません。非 Unity パッケージの扱いについては、Unity の [ベストプラクティス](/authentication/approaches-to-authentication.md.md) を参照してください。

> **Warning:**
>
> **重要**: Unity Authentication では、セキュリティ上の理由から、タイムスタンプ入力は 10 分間だけ有効となります。SignInWithAppleGameCenterAsync または LinkWithAppleGameCenterAsync を呼び出す前に、Apple の FetchItems API を呼び出して新しい入力を受け取れるようにしてください。SignInWithAppleGameCenterAsync または LinkWithAppleGameCenterAsync への呼び出しが 1 回正常に行われば、これらの API をそれ以上呼び出す必要はありません。

必要なプラグインをインストールし、ID プロバイダーを設定したら、以下のサンプルコードを使用して ID の検証に必要なパラメーターを取得できます。

```cs
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.");
        }
    }
}
```

## 戻ってきたプレイヤーのサインインまたは新しいプレイヤーの作成##sign-in-a-returning-player-or-create-new-player

`SignInWithAppleGameCenterAsync` メソッドを使用して、以下のいずれかを行うことができます。

* Apple Game Center の認証情報を使用して新しい Unity Authentication プレイヤーを作成する。
* Apple Game Center の認証情報を使用して既存のプレイヤーをサインインする。

プロジェクト内の Unity Authentication プレイヤーが認証情報と関連付けられていない場合、`SignInWithAppleGameCenterAsync` は新しいプレイヤーを作成します。プロジェクト内の Unity Authentication プレイヤーが認証情報と関連付けられている場合、`SignInWithAppleCenterAsync` はそのプレイヤーのアカウントにサインインします。この関数ではキャッシュされたプレイヤーは考慮されません。`SignInWithAppleGameCenterAsync` はキャッシュされたプレイヤーを置き換えます。

```cs
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);
    }
}
```

## プレイヤーを匿名から Apple Game Center アカウントへと更新する##updating-a-player-from-anonymous-to-an-apple-game-center-account

匿名認証を設定した後、プレイヤーが匿名からアップグレードして Apple Game Center アカウントを作成し、Apple Game Center を使用してサインインすることを希望する場合は、ゲームのプレイヤーにプロンプトを表示し、Apple Game Center サインインをトリガーして GameKit から ID 検証パラメーターを取得するよう求める必要があります。その後、`LinkWithAppleGameCenterAsync` API を呼び出して、プレイヤーを Apple Game Center の teamPlayerID にリンクします。

キャッシュされたプレイヤーが SDK に存在する場合は、キャッシュされたプレイヤーを Apple Game Center アカウントにリンクできます。

1. `SignInAnonymouslyAsync` を使用して、キャッシュされたプレイヤーのアカウントにサインインします。
2. `LinkWithAppleGameCenterAsync` を使用して、キャッシュされたプレイヤーのアカウントを Apple アカウントにリンクします。

```cs
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);
    }
}
```

## Apple Game Center アカウントをリンク解除する##unlink-apple-game-center-account

`UnlinkAppleGameCenterAsync` API を使用して、プレイヤーが自身の Apple Game Center アカウントをリンク解除できるようにします。リンク解除後、そのアカウントが他のどの ID にもリンクされていない場合、そのアカウントは匿名アカウントに遷移します。

```cs
async Task UnlinkAppleGameCenterAsync(string idToken)
{
   try
   {
       await AuthenticationService.Instance.UnlinkAppleGameCenterAsync(idToken);
       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);
   }
}
```
