1. アカウントを作成してログインする
まずはゲームにログインできるようにしましょう。ログインしたプレイヤーの ID を画面に表示し、Unity の再生を止めても、同じアカウントで戻ってこられるようにします。
初回はアカウントを作成して、プレイヤー ID とパスワードを保存します。2 回目からは保存した情報でログインします。ログイン後に受け取るアクセストークンには期限があるので、次に起動するときもログイン処理を通します。
1. プレイヤーを保存する場所を作る
GS2 の設定やデータを分けて置く場所を「ネームスペース」と呼びます。プレイヤーのアカウントを保存するために、GS2-Account のネームスペースを作りましょう。
「引き継ぎ設定」を追加する
Studio の Adventure プロジェクトを開きます。左側で機能を追加を押し、検索欄に 引き継ぎ と入力してください。メニューが見当たらない場合は、右上のシンプルを選びます。
引き継ぎ設定のカードで、追加を押します。このパッケージには、プレイヤーのアカウントを保存する Account の設定も入っています。
カードに追加済みと表示されたら、Studio への読み込みは完了です。
サーバーに反映する
追加した設定を GS2 に送って、実際にアカウントを保存できるようにします。この作業を「デプロイ」と呼びます。
左側で反映を押し、サーバに反映するの枠にあるサーバとの差分を確認を押してください。
GS2 ログインが表示されたら、準備で登録した開発者アカウントのメールアドレスとパスワードでログインします。
ログインできたら、デプロイ先と変更内容を確認します。
- GS2プロジェクト選択で、学習用の
adventureプロジェクトと 東京(ap-northeast-1) を選び、選択を押します。 - GS2への変更を確認で、引き継ぎ設定のパッケージ
foundation-core-identityの差分を確認します。新しいプロジェクトでは、Accountというネームスペースが作られます。スタック名は Studio が用意した名前を使います。 - 1パッケージをデプロイを押し、処理が完了するまで待ちます。
- 反映に戻り、サーバに反映するの枠が最新の内容を反映済みになっていることを確認します。
これで、プレイヤーを保存する Account ネームスペースができました。
コンソールから Account を作る
SDK コースでは、adventure-account というネームスペースをテンプレートから作ります。
- マネージメントコンソールで、学習用プロジェクトの東京リージョンを開きます。
- Deploy → スタックリスト → スタックを新規作成を選びます。
- 下のリンクからテンプレートをダウンロードします。スタック名を
adventure-loginにし、テンプレートデータでダウンロードした01-account.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.Name2. Unity にログイン処理を追加する
SDK と生成コードを Unity に入れる
追加した「引き継ぎ設定」を Unity から使うために、必要なファイルを Unity プロジェクトへ書き出します。この操作で、GS2 と通信する SDK、ログイン用のコンポーネントを含む GS2-Bind、選んだ機能を呼び出すための C# コードがそろいます。
Studio の Adventure プロジェクトと、準備のページで作った Unity プロジェクトを開いておきましょう。Unity は再生を止め、Adventure シーンを保存しておきます。
1. 書き出す先の Unity プロジェクトを選ぶ
左側で反映を押します。Unity プロジェクトを更新するの枠にある、Unityプロジェクトを選択して更新を押してください。
フォルダーを選ぶ画面が開きます。選ぶのは、Assets・Packages・ProjectSettings が入っているフォルダーです。Unity プロジェクトの名前が AdventureUnity なら、次の AdventureUnity を選びます。
AdventureUnity/ ← このフォルダーを選ぶ
├── Assets/
├── Packages/
└── ProjectSettings/Assets フォルダーや、Studio の設計データを保存したフォルダーを選ぶと、Unity プロジェクトとして更新できません。
フォルダーを選ぶと、更新内容の確認画面が開きます。更新先が自分の Unity プロジェクトになっていることを確認して、更新を押します。画像の更新先は撮影用の例です。
この操作で、Assets/GS2Studio/Generated に C# コードを書き出し、Unity のパッケージ設定に SDK と GS2-Bind を追加します。Generated の中は更新時に作り直されるので、自分で書くスクリプトはその外に置きます。
2. Studio で書き出しの完了を確認する
更新が終わったら、Unity プロジェクトを更新するの枠を見ます。
- 最新の内容を反映済みと表示されている。
- 枠の下部にあるUnity プロジェクトが、選んだフォルダーになっている。
- 生成先に
Assets/GS2Studio/Generatedと表示されている。
一度連携すると、ボタンは連携中のUnityプロジェクトを更新に変わります。次に書き出すときは、このボタンを使います。書き出し先を変えるときは、表示されたフォルダーの右側にある変更して更新から選び直せます。
3. Unity でファイルの読み込みを確認する
- Unity Editor に戻ります。必要なパッケージのダウンロードと、C# コードのコンパイルが始まるので、処理が終わるまで待ちます。
- Project ウィンドウで Assets → GS2Studio → Generated を開き、C# ファイルが入っていることを確認します。Project ウィンドウが見当たらない場合は、Window → General → Project で開けます。
- Window → Package Manager を開き、プロジェクトに導入済みのパッケージ一覧で
GS2を検索します。io.gs2.bind、io.gs2.csharp.sdk、io.gs2.unity.sdkの3パッケージが入っていることを確認します。パッケージ ID は、各パッケージを選んだ詳細欄で確認できます。 - 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 |
画像では認証情報を空欄にしています。自分のプロジェクトでは、上の表の値を入力してください。
シーンで 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 を一致させてください。アセットのファイル名だけを変えても、この設定にはなりません。
同じアカウントを使えるようにイベントをつなぐ
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. 表示用のテキストを作る
- GameObject → UI (Canvas) → Text - TextMeshPro を選び、名前を
PlayerIdTextにします。Canvas がない場合は、一緒に作成されます。 - TMP Importer が開いたら、Import TMP Essentials を押します。
- 日本語を表示するため、Noto Sans JP のフォントファイル(別タブ)を開き、Download raw file でダウンロードします。Unity の Project ウィンドウで
Assets/Fontsフォルダーを作り、NotoSansJP-Regular.otfをドラッグして入れます。 - 入れたフォントを選び、Assets → Create → TextMeshPro → Font Asset → SDF を選びます。作成された Font Asset の名前を
AdventureFontにし、Inspector の Atlas Population Mode を Dynamic にします。 - Hierarchy で
PlayerIdTextを選び、TextMeshPro の Font Asset にAdventureFontを割り当てます。 - Rect Transform で、画面上部に表示されるように位置と横幅を調整します。長い ID も読めるよう、横幅を広めに取ります。
- TextMeshPro の Text Input は空にします。表示する文字は、ログイン後にコンポーネントから受け取ります。
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 側を使ってください。
これでログインに成功すると ID が表示されます。保存したアカウントでログインし直したときや、ログイン後にこのテキストを有効にしたときも、現在の ID に更新されます。
ログイン中とエラーのメッセージを表示する
ID の表示とは別に、ログインの状況が分かるテキストも用意しましょう。
- Canvas の下にもう一つ Text - TextMeshPro を作り、名前を
LoginStatusにします。PlayerIdTextの下に配置します。 - Font Asset に先ほど作った
AdventureFontを割り当て、Text Input にログイン中ですと入力します。 Gs2の AutoLogin にある On Auto Login Complete の + を押し、LoginStatusを割り当てます。TextMeshProUGUI → text の固定文字列を指定できる項目を選び、文字列の入力欄を空にします。ログインできたら、メッセージの文字だけが消えます。- Client Holder と AutoLogin の On Error に、それぞれ
LoginStatusを割り当てます。TextMeshProUGUI → text の固定文字列を指定できる項目を選び、ログインできませんでした。設定と接続を確認してくださいと入力します。こちらは Dynamic 側ではありません。
シーンを保存してから再生します。ログイン中のメッセージが消え、プレイヤー ID が表示されれば成功です。
ログイン用のスクリプトを付ける
SDK の非同期処理は UniTask で待ちます。await の次の行は通信が完了してから実行され、エラーは catch で受け取ります。
Assets/AdventureLogin.csを作り、下のコードを貼り付けます。- シーンに空の GameObject を作り、名前を
Adventureにします。 AdventureLoginを追加し、Inspector の Client Id と Client Secret にDefaultのアウトプットを設定します。- Account Namespace は
adventure-account、Account Slot はmainにします。 - 再生すると画面左上にログインボタンが出ます。押して、プレイヤー ID が表示されることを確認します。
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; }
}
}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 に戻ることを確認してください。










