> For the complete documentation index, see [llms.txt](/ja/llms.txt)


# 1. アカウントを作成してログインする

プレイヤーのアカウントを作り、保存した情報でログインし直せるようにします。



まずはゲームにログインできるようにしましょう。ログインしたプレイヤーの ID を画面に表示し、Unity の再生を止めても、同じアカウントで戻ってこられるようにします。

初回はアカウントを作成して、プレイヤー ID とパスワードを保存します。2 回目からは保存した情報でログインします。ログイン後に受け取るアクセストークンには期限があるので、次に起動するときもログイン処理を通します。

## 1. プレイヤーを保存する場所を作る

GS2 の設定やデータを分けて置く場所を「ネームスペース」と呼びます。プレイヤーのアカウントを保存するために、GS2-Account のネームスペースを作りましょう。


**Studio**

### 「引き継ぎ設定」を追加する

Studio の `Adventure` プロジェクトを開きます。左側で**機能を追加**を押し、検索欄に `引き継ぎ` と入力してください。メニューが見当たらない場合は、右上の**シンプル**を選びます。

**引き継ぎ設定**のカードで、**追加**を押します。このパッケージには、プレイヤーのアカウントを保存する Account の設定も入っています。

<a href="/images/adventure/studio-2026-11-3/identity-search.jpg" target="_blank" rel="noopener" aria-label="「機能を追加」で引き継ぎ設定を検索した画面。カードの「追加」を押す（別タブで拡大）"><img src="/images/adventure/studio-2026-11-3/identity-search.jpg" alt="「機能を追加」で引き継ぎ設定を検索した画面。カードの「追加」を押す" loading="lazy"></a>

カードに**追加済み**と表示されたら、Studio への読み込みは完了です。

<a href="/images/adventure/studio-2026-11-3/identity-added.jpg" target="_blank" rel="noopener" aria-label="引き継ぎ設定のカードに「追加済み」と表示された状態（別タブで拡大）"><img src="/images/adventure/studio-2026-11-3/identity-added.jpg" alt="引き継ぎ設定のカードに「追加済み」と表示された状態" loading="lazy"></a>

### サーバーに反映する

追加した設定を GS2 に送って、実際にアカウントを保存できるようにします。この作業を「デプロイ」と呼びます。

左側で**反映**を押し、**サーバに反映する**の枠にある**サーバとの差分を確認**を押してください。

<a href="/images/adventure/studio-2026-11-3/identity-publish.jpg" target="_blank" rel="noopener" aria-label="反映画面の「サーバに反映する」から「サーバとの差分を確認」を押す（別タブで拡大）"><img src="/images/adventure/studio-2026-11-3/identity-publish.jpg" alt="反映画面の「サーバに反映する」から「サーバとの差分を確認」を押す" loading="lazy"></a>

**GS2 ログイン**が表示されたら、準備で登録した開発者アカウントのメールアドレスとパスワードでログインします。

<a href="/images/adventure/studio-2026-11-3/identity-gs2-login.jpg" target="_blank" rel="noopener" aria-label="GS2 の開発者アカウントでログインする画面（別タブで拡大）"><img src="/images/adventure/studio-2026-11-3/identity-gs2-login.jpg" alt="GS2 の開発者アカウントでログインする画面" loading="lazy"></a>

ログインできたら、デプロイ先と変更内容を確認します。

1. **GS2プロジェクト選択**で、学習用の `adventure` プロジェクトと **東京（ap-northeast-1）** を選び、**選択**を押します。
2. **GS2への変更を確認**で、引き継ぎ設定のパッケージ `foundation-core-identity` の差分を確認します。新しいプロジェクトでは、`Account` というネームスペースが作られます。スタック名は Studio が用意した名前を使います。
3. **1パッケージをデプロイ**を押し、処理が完了するまで待ちます。
4. **反映**に戻り、**サーバに反映する**の枠が**最新の内容を反映済み**になっていることを確認します。

これで、プレイヤーを保存する `Account` ネームスペースができました。


**SDK（Unity）**

### コンソールから Account を作る

SDK コースでは、`adventure-account` というネームスペースをテンプレートから作ります。

1. マネージメントコンソールで、学習用プロジェクトの**東京リージョン**を開きます。
2. **Deploy → スタックリスト → スタックを新規作成**を選びます。
3. 下のリンクからテンプレートをダウンロードします。スタック名を `adventure-login` にし、**テンプレートデータ**でダウンロードした `01-account.yaml` を選びます。
4. **作成**を押し、実行状態が**作成完了**になるまで待ちます。

```yaml
GS2TemplateFormatVersion: "2019-05-01"
Description: Adventure tutorial - player accounts
Resources:
  AccountNamespace:
    Type: GS2::Account::Namespace
    Properties:
      Name: adventure-account
Outputs:
  AccountNamespaceName: !GetAttr AccountNamespace.Item.Name
```

<a href="/samples/adventure/01-account.yaml" download>このテンプレートをダウンロード</a>




## 2. Unity にログイン処理を追加する


**Studio**

### SDK と生成コードを Unity に入れる

追加した「引き継ぎ設定」を Unity から使うために、必要なファイルを Unity プロジェクトへ書き出します。この操作で、GS2 と通信する SDK、ログイン用のコンポーネントを含む GS2-Bind、選んだ機能を呼び出すための C# コードがそろいます。

Studio の `Adventure` プロジェクトと、準備のページで作った Unity プロジェクトを開いておきましょう。Unity は再生を止め、`Adventure` シーンを保存しておきます。

#### 1. 書き出す先の Unity プロジェクトを選ぶ

左側で**反映**を押します。**Unity プロジェクトを更新する**の枠にある、**Unityプロジェクトを選択して更新**を押してください。

<a href="/images/adventure/studio-2026-11-3/identity-publish.jpg" target="_blank" rel="noopener" aria-label="反映画面。中央の「Unity プロジェクトを更新する」の枠から、Unity プロジェクトを選べる（別タブで拡大）"><img src="/images/adventure/studio-2026-11-3/identity-publish.jpg" alt="反映画面。中央の「Unity プロジェクトを更新する」の枠から、Unity プロジェクトを選べる" loading="lazy"></a>

フォルダーを選ぶ画面が開きます。選ぶのは、**`Assets`・`Packages`・`ProjectSettings` が入っているフォルダー**です。Unity プロジェクトの名前が `AdventureUnity` なら、次の `AdventureUnity` を選びます。

```text
AdventureUnity/           ← このフォルダーを選ぶ
├── Assets/
├── Packages/
└── ProjectSettings/
```

`Assets` フォルダーや、Studio の設計データを保存したフォルダーを選ぶと、Unity プロジェクトとして更新できません。

フォルダーを選ぶと、更新内容の確認画面が開きます。**更新先**が自分の Unity プロジェクトになっていることを確認して、**更新**を押します。画像の更新先は撮影用の例です。

<a href="/images/adventure/studio-2026-11-3/identity-unity-confirm.jpg" target="_blank" rel="noopener" aria-label="Unity の更新内容を確認する画面。更新先と追加される SDK を確認し、右下の「更新」を押す（別タブで拡大）"><img src="/images/adventure/studio-2026-11-3/identity-unity-confirm.jpg" alt="Unity の更新内容を確認する画面。更新先と追加される SDK を確認し、右下の「更新」を押す" loading="lazy"></a>

この操作で、`Assets/GS2Studio/Generated` に C# コードを書き出し、Unity のパッケージ設定に SDK と GS2-Bind を追加します。`Generated` の中は更新時に作り直されるので、自分で書くスクリプトはその外に置きます。

#### 2. Studio で書き出しの完了を確認する

更新が終わったら、**Unity プロジェクトを更新する**の枠を見ます。

- **最新の内容を反映済み**と表示されている。
- 枠の下部にある**Unity プロジェクト**が、選んだフォルダーになっている。
- **生成先**に `Assets/GS2Studio/Generated` と表示されている。

<a href="/images/adventure/studio-2026-11-3/identity-unity-updated.jpg" target="_blank" rel="noopener" aria-label="書き出し完了後。「最新の内容を反映済み」と表示され、枠の下部に Unity プロジェクトと生成先が載っている（別タブで拡大）"><img src="/images/adventure/studio-2026-11-3/identity-unity-updated.jpg" alt="書き出し完了後。「最新の内容を反映済み」と表示され、枠の下部に Unity プロジェクトと生成先が載っている" loading="lazy"></a>

一度連携すると、ボタンは**連携中のUnityプロジェクトを更新**に変わります。次に書き出すときは、このボタンを使います。書き出し先を変えるときは、表示されたフォルダーの右側にある**変更して更新**から選び直せます。

#### 3. Unity でファイルの読み込みを確認する

1. Unity Editor に戻ります。必要なパッケージのダウンロードと、C# コードのコンパイルが始まるので、処理が終わるまで待ちます。
2. **Project** ウィンドウで **Assets → GS2Studio → Generated** を開き、C# ファイルが入っていることを確認します。Project ウィンドウが見当たらない場合は、**Window → General → Project** で開けます。
3. **Window → Package Manager** を開き、プロジェクトに導入済みのパッケージ一覧で `GS2` を検索します。`io.gs2.bind`、`io.gs2.csharp.sdk`、`io.gs2.unity.sdk` の3パッケージが入っていることを確認します。パッケージ ID は、各パッケージを選んだ詳細欄で確認できます。
4. **Window → General → Console** を開き、赤いコンパイルエラーが出ていないことを確認します。

パッケージのダウンロードに失敗している場合は、Package Manager に表示されたエラーとネットワーク接続を確認してください。C# のエラーがある場合は、Console の赤い項目を選ぶと詳細を読めます。

### 接続設定を作る

Unity の Project ウィンドウで右クリックし、**Create → Game Server Services → Core → Environment** を選びます。作成したアセットを `AdventureEnvironment` とし、Inspector を次のように設定します。

| 項目 | 入れる値 |
| --- | --- |
| Name | `adventure` |
| Region | `ApNortheast1` |
| Client Id | `Default` の `ApplicationClientId` |
| Client Secret | `Default` の `ApplicationClientSecret` |

画像では認証情報を空欄にしています。自分のプロジェクトでは、上の表の値を入力してください。

<a href="/images/adventure/unity-6000-3/environment.jpg" target="_blank" rel="noopener" aria-label="AdventureEnvironment の Inspector。Name は adventure、Region は Ap Northeast 1（別タブで拡大）"><img src="/images/adventure/unity-6000-3/environment.jpg" alt="AdventureEnvironment の Inspector。Name は adventure、Region は Ap Northeast 1" loading="lazy"></a>

シーンで **GameObject → Create Empty** を選び、名前を `Gs2` にします。Inspector の **Add Component** から、次のコンポーネントを追加します。

| コンポーネント | 設定 |
| --- | --- |
| `GS2/Core/Gs2ClientHolder` | Environments に `AdventureEnvironment` を1件追加。Active Environment Name は `adventure` |
| `GS2/Core/Gs2GameSessionHolder` | 追加した状態で使う |
| `GS2/Account/AutoLogin` | Account Namespace は `Account`。Persist Account をオン |
| `GS2/Account/PlayerPrefs Account Store` | Key Prefix を `adventure.main` にする |
| `GS2 Studio/Runtime/Gs2HolderRuntimeContextProvider` | Client Holder と Session Holder に、上で追加したコンポーネントを割り当てる |

`Environment` の **Name** 欄と、Client Holder の **Active Environment Name** を一致させてください。アセットのファイル名だけを変えても、この設定にはなりません。

<a href="/images/adventure/unity-6000-3/client-holder.jpg" target="_blank" rel="noopener" aria-label="Gs2 の Inspector。Client Holder の Environments に AdventureEnvironment を割り当てる（別タブで拡大）"><img src="/images/adventure/unity-6000-3/client-holder.jpg" alt="Gs2 の Inspector。Client Holder の Environments に AdventureEnvironment を割り当てる" loading="lazy"></a>

### 同じアカウントを使えるようにイベントをつなぐ

AutoLogin のイベント欄で **＋** を押し、同じ `Gs2` オブジェクトを割り当てます。関数の選択では、引数を受け取る **Dynamic** 側を選んでください。

| AutoLogin のイベント | 接続する関数 |
| --- | --- |
| On Account Created | `Gs2PlayerPrefsAccountStore.Remember`（Dynamic の string, string） |
| On Restore Account | `Gs2PlayerPrefsAccountStore.Restore`（Dynamic の Gs2AutoLoginAction） |

Persist Account をオンにするだけでなく、この二つの接続が必要です。これで、初回に発行されたアカウント情報が保存され、次回の再生時に読み込まれます。

### プレイヤー ID を表示する

Unity のテキストと **Player ID Label** をつなぎ、ログインしたプレイヤーの ID を表示します。

#### 1. 表示用のテキストを作る

1. **GameObject → UI (Canvas) → Text - TextMeshPro** を選び、名前を `PlayerIdText` にします。Canvas がない場合は、一緒に作成されます。
2. **TMP Importer** が開いたら、**Import TMP Essentials** を押します。
3. 日本語を表示するため、<a href="https://github.com/notofonts/noto-cjk/blob/main/Sans/SubsetOTF/JP/NotoSansJP-Regular.otf" target="_blank" rel="noopener">Noto Sans JP のフォントファイル（別タブ）</a>を開き、**Download raw file** でダウンロードします。Unity の Project ウィンドウで `Assets/Fonts` フォルダーを作り、`NotoSansJP-Regular.otf` をドラッグして入れます。
4. 入れたフォントを選び、**Assets → Create → TextMeshPro → Font Asset → SDF** を選びます。作成された Font Asset の名前を `AdventureFont` にし、Inspector の **Atlas Population Mode** を **Dynamic** にします。
5. Hierarchy で `PlayerIdText` を選び、TextMeshPro の **Font Asset** に `AdventureFont` を割り当てます。
6. Rect Transform で、画面上部に表示されるように位置と横幅を調整します。長い ID も読めるよう、横幅を広めに取ります。
7. TextMeshPro の **Text Input** は空にします。表示する文字は、ログイン後にコンポーネントから受け取ります。

<a href="/images/adventure/unity-6000-3/text-font.jpg" target="_blank" rel="noopener" aria-label="PlayerIdText の TextMeshPro 設定。Font Asset に AdventureFont を割り当て、Text Input は空にする（別タブで拡大）"><img src="/images/adventure/unity-6000-3/text-font.jpg" alt="PlayerIdText の TextMeshPro 設定。Font Asset に AdventureFont を割り当て、Text Input は空にする" loading="lazy"></a>

#### 2. Player ID Label をつなぐ

`PlayerIdText` を選んだまま、Inspector の **Add Component → GS2 → Core → Player ID Label** を選びます。

| 項目 | 設定 |
| --- | --- |
| Session Holder | Hierarchy の `Gs2` をドラッグして割り当てる |
| Format | `プレイヤー ID: {userId}` |

**On Update** の **＋** を押し、`PlayerIdText` 自身を割り当てます。関数の一覧から **TextMeshProUGUI → Dynamic string → text** を選びます。入力欄に固定の文字を書く項目ではなく、受け取った文字列を表示する **Dynamic string** 側を使ってください。

<a href="/images/adventure/unity-6000-3/player-id-label.jpg" target="_blank" rel="noopener" aria-label="Player ID Label の設定。Session Holder は Gs2、On Update は PlayerIdText の TextMeshProUGUI.text に接続する（別タブで拡大）"><img src="/images/adventure/unity-6000-3/player-id-label.jpg" alt="Player ID Label の設定。Session Holder は Gs2、On Update は PlayerIdText の TextMeshProUGUI.text に接続する" loading="lazy"></a>

これでログインに成功すると ID が表示されます。保存したアカウントでログインし直したときや、ログイン後にこのテキストを有効にしたときも、現在の ID に更新されます。

### ログイン中とエラーのメッセージを表示する

ID の表示とは別に、ログインの状況が分かるテキストも用意しましょう。

1. Canvas の下にもう一つ **Text - TextMeshPro** を作り、名前を `LoginStatus` にします。`PlayerIdText` の下に配置します。
2. **Font Asset** に先ほど作った `AdventureFont` を割り当て、**Text Input** に `ログイン中です` と入力します。
3. `Gs2` の AutoLogin にある **On Auto Login Complete** の **＋** を押し、`LoginStatus` を割り当てます。**TextMeshProUGUI → text** の固定文字列を指定できる項目を選び、文字列の入力欄を空にします。ログインできたら、メッセージの文字だけが消えます。
4. Client Holder と AutoLogin の **On Error** に、それぞれ `LoginStatus` を割り当てます。**TextMeshProUGUI → text** の固定文字列を指定できる項目を選び、`ログインできませんでした。設定と接続を確認してください` と入力します。こちらは **Dynamic** 側ではありません。

<a href="/images/adventure/unity-6000-3/login-events.jpg" target="_blank" rel="noopener" aria-label="AutoLogin のイベント設定。Remember と Restore でアカウントを保存・復元し、完了時は LoginStatus の文字を消す。Key Prefix は adventure.main（別タブで拡大）"><img src="/images/adventure/unity-6000-3/login-events.jpg" alt="AutoLogin のイベント設定。Remember と Restore でアカウントを保存・復元し、完了時は LoginStatus の文字を消す。Key Prefix は adventure.main" loading="lazy"></a>

シーンを保存してから再生します。ログイン中のメッセージが消え、プレイヤー ID が表示されれば成功です。


**SDK（Unity）**

### ログイン用のスクリプトを付ける

SDK の非同期処理は UniTask で待ちます。`await` の次の行は通信が完了してから実行され、エラーは `catch` で受け取ります。

1. `Assets/AdventureLogin.cs` を作り、下のコードを貼り付けます。
2. シーンに空の GameObject を作り、名前を `Adventure` にします。
3. `AdventureLogin` を追加し、Inspector の Client Id と Client Secret に `Default` のアウトプットを設定します。
4. Account Namespace は `adventure-account`、Account Slot は `main` にします。
5. 再生すると画面左上に**ログイン**ボタンが出ます。押して、プレイヤー ID が表示されることを確認します。

```csharp
using Cysharp.Threading.Tasks;
using Gs2.Core.Model;
using Gs2.Unity.Core;
using Gs2.Unity.Util;
using UnityEngine;

public sealed class AdventureLogin : MonoBehaviour
{
    [SerializeField] private string clientId = "YOUR_CLIENT_ID";
    [SerializeField] private string clientSecret = "YOUR_CLIENT_SECRET";
    [SerializeField] private string accountNamespace = "adventure-account";
    [SerializeField] private string accountSlot = "main";

    public Gs2Domain Gs2 { get; private set; }
    public GameSession Session { get; private set; }
    private bool busy;
    private string message = "ログインしてください";
    private string SaveKey => $"adventure.{clientId}.{accountNamespace}.{accountSlot}";

    private void OnGUI()
    {
        GUILayout.BeginArea(new Rect(20, 20, 650, 170), GUI.skin.box);
        GUILayout.Label(message);
        GUI.enabled = !busy && Session == null;
        GUILayout.Label("保存先（main / practice など）");
        accountSlot = GUILayout.TextField(accountSlot);
        if (GUILayout.Button("ログイン")) Login().Forget();
        GUI.enabled = true;
        GUILayout.EndArea();
    }

    private async UniTask Login()
    {
        busy = true;
        message = "ログイン中です";
        try
        {
            if (Gs2 == null)
            {
                Gs2 = await Gs2Client.CreateAsync(
                    new BasicGs2Credential(clientId, clientSecret), Region.ApNortheast1);
            }

            var userId = PlayerPrefs.GetString(SaveKey + ".userId", "");
            var password = PlayerPrefs.GetString(SaveKey + ".password", "");
            if (string.IsNullOrEmpty(userId) != string.IsNullOrEmpty(password))
            {
                message = "保存したアカウント情報がそろっていません。保存先を確認してください";
                return;
            }
            if (string.IsNullOrEmpty(userId))
            {
                var create = await Gs2.Account.Namespace(accountNamespace).CreateAsync();
                var model = await create.ModelAsync();
                userId = model.UserId;
                password = model.Password;
                PlayerPrefs.SetString(SaveKey + ".userId", userId);
                PlayerPrefs.SetString(SaveKey + ".password", password);
                PlayerPrefs.Save();
            }

            var login = await Gs2.LoginAsync(
                new Gs2AccountAuthenticator(new AccountSetting
                {
                    accountNamespaceName = accountNamespace,
                    keyId = "grn:gs2:{region}:{ownerId}:key:default:key:default"
                }), userId, password);
            Session = login;
            message = "ログインしました。プレイヤー ID: " + Session.AccessToken.UserId;
        }
        catch (System.Exception error) { message = "接続できませんでした: " + error.GetType().Name; }
        finally { busy = false; }
    }
}
```

<a href="/samples/adventure/AdventureLogin.cs" download>AdventureLogin.cs をダウンロード</a>

`AccountSetting.keyId` の `{region}` と `{ownerId}` は GS2 が解決する既定鍵の指定です。このコードではそのまま使います。鍵のネームスペース名と鍵名は、どちらも `default` です。

新しいアカウントの情報は、ログインの前に保存しています。ログイン時の通信に失敗しても、次に押したときに同じアカウントで試せます。保存済みの情報でログインできなかった場合も、勝手に別のアカウントを作りません。




この教材では、端末内の保存先に `PlayerPrefs` を使います。暗号化されない保存領域なので、公開するゲームでは保存方法を選び直してください。プレイヤーのパスワードや Client Secret を画面・ログ・公開リポジトリへ載せないようにします。

## 3. 同じアカウントでログインし直す

一度再生を止め、もう一度ログインしてみましょう。プレイヤー ID が前と同じなら、保存したアカウントでログインできています。

| 操作 | 期待する結果 |
| --- | --- |
| 初回のログイン | プレイヤー ID が表示される |
| Unity の Play を止め、もう一度再生してログイン | 同じ ID が表示される |
| 再生を止め、ネットワークを切断してから再生・ログイン | エラーメッセージが表示される |
| ネットワークを戻し、再生を止めてもう一度再生・ログイン | 保存したアカウントでログインできる |

Studio では再生を始めると自動ログインします。SDK では画面のログインボタンを押します。再生を止めても保存データは残ります。

## 練習：二人目のプレイヤーを作る

Studio では再生を止めて PlayerPrefs Account Store の **Key Prefix** を `adventure.practice` に変え、再生します。SDK でも再生を止め、`AdventureLogin` の Inspector で **Account Slot** を `practice` に変えて再生し、ログインします。元と異なるプレイヤー ID になったでしょうか。

試し終わったら再生を止め、Studio の Key Prefix を **`adventure.main`**、SDK の Account Slot を **`main`** に戻して再生し、ログインします。最初のプレイヤー ID に戻ることを確認してください。

[次へ：冒険を登録して一覧に表示する]()



