パスコード

パスコードマッチメイキングを GS2 SDK for Unity から利用する手順を解説します。

パスコードマッチメイキング とは

身近なフレンドとの対戦・協力プレイを実現するための方式で、

親となるユーザがルーム(ギャザリング)を作成し、作成が成功するとそのルームに参加するためのパスコードが発行されます。

ルームに参加するユーザはパスコードを入力することで、そのルームに参加できます。

ギャザリングプールを作成する

まずは、マッチメイキングが成立した後で GS2-Realtime と連携するために、GS2-Realtime の初期設定を行います。

GS2マネージメントコンソールの GS2-Realtime から新しいギャザリングプールを作成します。

../../../../_images/step-00014.png

『ギャザリングプールの新規作成』をクリックします。

../../../../_images/step-00024.png

ギャザリングプールの名前や説明を記入し『作成』ボタンをクリックします。

これで GS2-Realtime が利用できる状態になりました。

マッチメイキングを作成する

GS2マネージメントコンソールの GS2-Matchmaking から新しくマッチメイキングを作成します。

../../../../_images/step-00033.png

『マッチメイキングの新規作成』をクリックします。

../../../../_images/step-00043.png

マッチメイキングの名前をつけて、種類に『パスコード』を指定します。

プレイヤー数 はマッチメイキングを成立させたい人数を指定します。

サービスクラスは想定されるアクセス数に応じたサイズを選択します。

マッチメイキングを成立時の挙動は『GS2-Realtime との自動連携』を選択します。

任意の方式でリアルタイム通信を実現したい場合は『独自サーバでのハンドリング』を選択することで、

マッチメイキング成立時に任意のURLに通知することができるようになります。

ギャザリングプールには先程作成した GS2-Realtime のギャザリングプールの名前を指定します。

これで、マッチメイキング成立時に自動的に GS2-Realtime と連携されゲームサーバが起動するようになります。

これで、GS2マネージメントコンソールでおこなう準備は完了です。

マッチメイキング処理を実装する

ここからは Unity での実装になります。

まずはログイン処理を実装する必要があります。ログインして Gs2.GameSession を取得するまでの手順は GS2-Auth をご参照ください。

ここからはログインが完了している前提で説明を進めます。

ルーム(ギャザリング)を作成する

gs2.Matchmaking.Passcode.Create() でギャザリングを作成します。

この処理はキューに積まれ、実際の処理は Dispatch() で行われます。

Dispatch() のイベントハンドラまたはコールバックで作成したギャザリングに参加するためのパスコードを得ることが出来ます。

ルーム(ギャザリング)に参加する

gs2.Matchmaking.Passcode.Join() でギャザリングに参加します。

この処理はキューに積まれ、実際の処理は Dispatch() で行われます。

マッチメイキング処理を行う

gs2.Matchmaking.Passcode.Dispatch() でマッチメイキング処理を実行します。

この処理はマッチメイキング開始後、マッチメイキングが完了するまで毎フレーム呼び出すようにしてください。

この処理はコルーチンで呼び出すことでブロックせずに処理を実行することが出来ます。

実装サンプル

GS2-Matchmaking のSDKはイベントハンドラ方式とコールバック方式の2種類のアプローチで実装することが出来ます。

イベントハンドラ方式

ルームオーナー

public class GameLogic : MonoBehaviour {

    private const string CLIENT_ID = "your client id";
    private const string CLIENT_SECRET = "your client secret";

    private const string MATCHMAKING_NAME = "matchmaking-0003";

    Gs2.Client gs2;
    Gs2.GameSession session;
    bool started;
    public static Gs2.Matchmaking.Gathering gathering;
    Gs2.Realtime.RealtimeSession rsession;

    void Start () {
        // GS2 Client を初期化
        gs2 = new Gs2.Client (new Gs2.Profile ()
            .ClientId (CLIENT_ID)
            .ClientSecret (CLIENT_SECRET));

        StartCoroutine (Login ());
    }

    IEnumerator Login() {
        // GS2-Account を利用して認証します
        string GAME_NAME = "game-0001";
        string KEY_NAME = "account";
        string USER_ID = "user";
        string PASSWORD = "password";
        string authenticationToken = null;
        yield return gs2.Account.Authentication (
            result => {
                if(result.Error != null) throw result.Error;
                authenticationToken = result.Result;
            },
            GAME_NAME,
            KEY_NAME,
            USER_ID,
            PASSWORD);

        // GS2-Account の認証情報を利用して GS2 にログインします
        yield return gs2.Auth.Login (
            result => {
                if(result.Error != null) throw result.Error;
                session = result.Result;
            },
            USER_ID,
            KEY_NAME,
            authenticationToken);

        StartCoroutine (CreateGathering ());
    }

    IEnumerator CreateGathering() {
        // ルーム(ギャザリング)を作成する
        Gs2.Matchmaking.PasscodeMatchmakingConfig config =
            new Gs2.Matchmaking.PasscodeMatchmakingConfig ()
                .MatchmakingName (MATCHMAKING_NAME)        // GS2-Matchmaking に作成したマッチメイキング名
                .Handler(new EventHandler());              // イベントハンドラ
        gs2.Matchmaking.Passcode.Create (session, config);
        started = true;
    }

    void Update () {
        if (started && gathering == null) {
            // マッチメイキングを開始しており、マッチメイキングが完了していない間呼び出す
            StartCoroutine (DoMatchmaking ());
        }
    }

    IEnumerator DoMatchmaking() {
        // マッチメイキング処理を実行する
        yield return gs2.Matchmaking.Passcode.Dispatch (
            result => {
                if(result.Error != null) throw result.Error;
                Gs2.Matchmaking.PasscodeEvent mmEvent = result.Result;
                // イベントハンドラ方式では、ここのコールバックは例外ハンドリング以外に使用する必要はありません
            },
            session);    // GS2 のログインセッション
    }
}

public class EventHandler : Gs2.Matchmaking.PasscodeMatchmakingEventHandler
{
    public void Create (string passcode)
    {
        // ギャザリングの作成が完了したときに呼び出されます
        Debug.Log ("ギャザリングに参加するためのパスコード: " + passcode);
    }

    public void Join (string gatheringId)
    {
        // ギャザリングへの参加が完了したときに呼び出されます
        Debug.Log ("参加したギャザリングID: " + gatheringId);
    }

    public void UpdateStatus (string[] joinedUserIds)
    {
        // 参加ユーザに変動があったときに呼び出されます
        Debug.Log ("[参加者]");
        foreach (string joinedUserId in joinedUserIds) {
            Debug.Log (joinedUserId);
        }
    }

    public void Complete(Gs2.Matchmaking.Gathering gathering)
    {
        // マッチメイキングが成立したときに呼び出されます
        Debug.Log ("GS2-Realtime のゲームサーバ情報: " + gathering.Host + ":" + gathering.Port);
        Debug.Log ("ゲームサーバとの通信に利用する暗号鍵: " + gathering.Secret);
        Debug.Log ("マッチメイキングされた通信相手");
        foreach (string joinedUserId in gathering.JoinedUserIds) {
            Debug.Log (joinedUserId);
        }
        GameLogic.gathering = gathering;
    }

    public void CancelAccept()
    {
        // マッチメイキングのキャンセルがサーバに受理されたときに呼び出されます
    }

    public void Failed(Gs2.Matchmaking.ErrorReason reason)
    {
        // 何らかの理由によりマッチメイキングが失敗したときに呼び出されます
        Debug.Log ("失敗理由: " + reason);
    }
}

ルーム参加

public class GameLogic : MonoBehaviour {

    private const string CLIENT_ID = "your client id";
    private const string CLIENT_SECRET = "your client secret";

    private const string MATCHMAKING_NAME = "matchmaking-0003";

    Gs2.Client gs2;
    Gs2.GameSession session;
    bool started;
    public static Gs2.Matchmaking.Gathering gathering;
    Gs2.Realtime.RealtimeSession rsession;

    void Start () {
        // GS2 Client を初期化
        gs2 = new Gs2.Client (new Gs2.Profile ()
            .ClientId (CLIENT_ID)
            .ClientSecret (CLIENT_SECRET));

        StartCoroutine (Login ());
    }

    IEnumerator Login() {
        // GS2-Account を利用して認証します
        string GAME_NAME = "game-0001";
        string KEY_NAME = "account";
        string USER_ID = "user";
        string PASSWORD = "password";
        string authenticationToken = null;
        yield return gs2.Account.Authentication (
            result => {
                if(result.Error != null) throw result.Error;
                authenticationToken = result.Result;
            },
            GAME_NAME,
            KEY_NAME,
            USER_ID,
            PASSWORD);

        // GS2-Account の認証情報を利用して GS2 にログインします
        yield return gs2.Auth.Login (
            result => {
                if(result.Error != null) throw result.Error;
                session = result.Result;
            },
            USER_ID,
            KEY_NAME,
            authenticationToken);

        StartCoroutine (JoinGathering ());
    }

    IEnumerator JoinGathering() {
        // ルーム(ギャザリング)に参加する
        Gs2.Matchmaking.PasscodeMatchmakingConfig config =
            new Gs2.Matchmaking.PasscodeMatchmakingConfig ()
                .MatchmakingName (MATCHMAKING_NAME)         // GS2-Matchmaking に作成したマッチメイキング名
                .Handler(new EventHandler());               // イベントハンドラ
        string PASSCODE = "00000000";                       // ギャザリングに参加するためのパスコード
        gs2.Matchmaking.Passcode.Join (session, config, PASSCODE);
        started = true;
    }

    void Update () {
        if (started && gathering == null) {
            // マッチメイキングを開始しており、マッチメイキングが完了していない間呼び出す
            StartCoroutine (DoMatchmaking ());
        }
    }

    IEnumerator DoMatchmaking() {
        // マッチメイキング処理を実行する
        yield return gs2.Matchmaking.Passcode.Dispatch (
            result => {
                if(result.Error != null) throw result.Error;
                Gs2.Matchmaking.PasscodeEvent mmEvent = result.Result;
                // イベントハンドラ方式では、ここのコールバックは例外ハンドリング以外に使用する必要はありません
            },
            session);    // GS2 のログインセッション
    }
}

public class EventHandler : Gs2.Matchmaking.PasscodeMatchmakingEventHandler
{
    public void Create (string passcode)
    {
        // ギャザリングの作成が完了したときに呼び出されます
        Debug.Log ("ギャザリングに参加するためのパスコード: " + passcode);
    }

    public void Join (string gatheringId)
    {
        // ギャザリングへの参加が完了したときに呼び出されます
        Debug.Log ("参加したギャザリングID: " + gatheringId);
    }

    public void UpdateStatus (string[] joinedUserIds)
    {
        // 参加ユーザに変動があったときに呼び出されます
        Debug.Log ("[参加者]");
        foreach (string joinedUserId in joinedUserIds) {
            Debug.Log (joinedUserId);
        }
    }

    public void Complete(Gs2.Matchmaking.Gathering gathering)
    {
        // マッチメイキングが成立したときに呼び出されます
        Debug.Log ("GS2-Realtime のゲームサーバ情報: " + gathering.Host + ":" + gathering.Port);
        Debug.Log ("ゲームサーバとの通信に利用する暗号鍵: " + gathering.Secret);
        Debug.Log ("マッチメイキングされた通信相手");
        foreach (string joinedUserId in gathering.JoinedUserIds) {
            Debug.Log (joinedUserId);
        }
        GameLogic.gathering = gathering;
    }

    public void CancelAccept()
    {
        // マッチメイキングのキャンセルがサーバに受理されたときに呼び出されます
    }

    public void Failed(Gs2.Matchmaking.ErrorReason reason)
    {
        // 何らかの理由によりマッチメイキングが失敗したときに呼び出されます
        Debug.Log ("失敗理由: " + reason);
    }
}

コールバック方式

イベントハンドラ方式では処理があちこちに分散してしまって好みではない。という開発者向けにコールバック方式の実装方式も提供しています。

ルームオーナー

public class GameLogic : MonoBehaviour {

    private const string CLIENT_ID = "your client id";
    private const string CLIENT_SECRET = "your client secret";

    private const string MATCHMAKING_NAME = "matchmaking-0003";

    Gs2.Client gs2;
    Gs2.GameSession session;
    bool started;
    public static Gs2.Matchmaking.Gathering gathering;
    Gs2.Realtime.RealtimeSession rsession;

    void Start () {
        // GS2 Client を初期化
        gs2 = new Gs2.Client (new Gs2.Profile ()
            .ClientId (CLIENT_ID)
            .ClientSecret (CLIENT_SECRET));

        StartCoroutine (Login ());
    }

    IEnumerator Login() {
        // GS2-Account を利用して認証します
        string GAME_NAME = "game-0001";
        string KEY_NAME = "account";
        string USER_ID = "user";
        string PASSWORD = "password";
        string authenticationToken = null;
        yield return gs2.Account.Authentication (
            result => {
                if(result.Error != null) throw result.Error;
                authenticationToken = result.Result;
            },
            GAME_NAME,
            KEY_NAME,
            USER_ID,
            PASSWORD);

        // GS2-Account の認証情報を利用して GS2 にログインします
        yield return gs2.Auth.Login (
            result => {
                if(result.Error != null) throw result.Error;
                session = result.Result;
            },
            USER_ID,
            KEY_NAME,
            authenticationToken);

        StartCoroutine (CreateGathering ());
    }

    IEnumerator CreateGathering() {
        // ルーム(ギャザリング)を作成する
        Gs2.Matchmaking.PasscodeMatchmakingConfig config =
            new Gs2.Matchmaking.PasscodeMatchmakingConfig ()
                .MatchmakingName (MATCHMAKING_NAME);        // GS2-Matchmaking に作成したマッチメイキング名
        gs2.Matchmaking.Passcode.Create (session, config);
        started = true;
    }

    void Update () {
        if (started && gathering == null) {
            // マッチメイキングを開始しており、マッチメイキングが完了していない間呼び出す
            StartCoroutine (DoMatchmaking ());
        }
    }

    IEnumerator DoMatchmaking() {
        // マッチメイキング処理を実行する
        yield return gs2.Matchmaking.Passcode.Dispatch (
            result => {
                if(result.Error != null) throw result.Error;
                Gs2.Matchmaking.PasscodeEvent mmEvent = result.Result;
                // イベントハンドラ方式と異なり、このコールバックで発生したイベントをハンドリングします
                if(mmEvent != null) {
                    switch(mmEvent.Type) {
                    case Gs2.Matchmaking.EventType.CREATE:
                        // ギャザリングの作成が完了したときに呼び出されます
                        Debug.Log ("ギャザリングに参加するためのパスコード: " + mmEvent.Passcode);
                        break;
                    case Gs2.Matchmaking.EventType.JOIN:
                        // ギャザリングへの参加が完了したときに呼び出されます
                        Debug.Log ("参加したギャザリングID: " + mmEvent.GatheringId);
                        break;
                    case Gs2.Matchmaking.EventType.UPDATE_STATUS:
                        // 参加ユーザに変動があったときに返されます
                        Debug.Log ("[参加者]");
                        foreach (string joinedUserId in mmEvent.JoinedUserIds) {
                            Debug.Log (joinedUserId);
                        }
                        break;
                    case Gs2.Matchmaking.EventType.COMPLETE:
                        // マッチメイキングが成立したときに返されます
                        Debug.Log ("GS2-Realtime のゲームサーバ情報: " + gathering.Host + ":" + gathering.Port);
                        Debug.Log ("ゲームサーバとの通信に利用する暗号鍵: " + gathering.Secret);
                        Debug.Log ("マッチメイキングされた通信相手");
                        foreach (string joinedUserId in gathering.JoinedUserIds) {
                            Debug.Log (joinedUserId);
                        }
                        gathering = mmEvent.Gathering;
                        break;
                    case Gs2.Matchmaking.EventType.CANCEL_ACCEPT:
                        // マッチメイキングのキャンセルがサーバに受理されたときに返されます
                        break;
                    case Gs2.Matchmaking.EventType.FAILED:
                        // 何らかの理由によりマッチメイキングが失敗したときに返されます
                        Debug.Log ("失敗理由: " + mmEvent.Reason);
                        break;
                    }
                }
            },
            session);    // GS2 のログインセッション
    }
}

ルーム参加

public class GameLogic : MonoBehaviour {

    private const string CLIENT_ID = "your client id";
    private const string CLIENT_SECRET = "your client secret";

    private const string MATCHMAKING_NAME = "matchmaking-0003";

    Gs2.Client gs2;
    Gs2.GameSession session;
    bool started;
    public static Gs2.Matchmaking.Gathering gathering;
    Gs2.Realtime.RealtimeSession rsession;

    void Start () {
        // GS2 Client を初期化
        gs2 = new Gs2.Client (new Gs2.Profile ()
            .ClientId (CLIENT_ID)
            .ClientSecret (CLIENT_SECRET));

        StartCoroutine (Login ());
    }

    IEnumerator Login() {
        // GS2-Account を利用して認証します
        string GAME_NAME = "game-0001";
        string KEY_NAME = "account";
        string USER_ID = "user";
        string PASSWORD = "password";
        string authenticationToken = null;
        yield return gs2.Account.Authentication (
            result => {
                if(result.Error != null) throw result.Error;
                authenticationToken = result.Result;
            },
            GAME_NAME,
            KEY_NAME,
            USER_ID,
            PASSWORD);

        // GS2-Account の認証情報を利用して GS2 にログインします
        yield return gs2.Auth.Login (
            result => {
                if(result.Error != null) throw result.Error;
                session = result.Result;
            },
            USER_ID,
            KEY_NAME,
            authenticationToken);

        StartCoroutine (JoinGathering ());
    }

    IEnumerator JoinGathering() {
        // ルーム(ギャザリング)に参加する
        Gs2.Matchmaking.PasscodeMatchmakingConfig config =
            new Gs2.Matchmaking.PasscodeMatchmakingConfig ()
                .MatchmakingName (MATCHMAKING_NAME);        // GS2-Matchmaking に作成したマッチメイキング名
        string PASSCODE = "00000000";                       // ギャザリングに参加するためのパスコード
        gs2.Matchmaking.Passcode.Join (session, config, PASSCODE);
        started = true;
    }

    void Update () {
        if (started && gathering == null) {
            // マッチメイキングを開始しており、マッチメイキングが完了していない間呼び出す
            StartCoroutine (DoMatchmaking ());
        }
    }

    IEnumerator DoMatchmaking() {
        // マッチメイキング処理を実行する
        yield return gs2.Matchmaking.Passcode.Dispatch (
            result => {
                if(result.Error != null) throw result.Error;
                Gs2.Matchmaking.PasscodeEvent mmEvent = result.Result;
                Gs2.Matchmaking.PasscodeEvent mmEvent = result.Result;
                // イベントハンドラ方式と異なり、このコールバックで発生したイベントをハンドリングします
                if(mmEvent != null) {
                    switch(mmEvent.Type) {
                    case Gs2.Matchmaking.EventType.CREATE:
                        // ギャザリングの作成が完了したときに呼び出されます
                        Debug.Log ("ギャザリングに参加するためのパスコード: " + mmEvent.Passcode);
                        break;
                    case Gs2.Matchmaking.EventType.JOIN:
                        // ギャザリングへの参加が完了したときに呼び出されます
                        Debug.Log ("参加したギャザリングID: " + mmEvent.GatheringId);
                        break;
                    case Gs2.Matchmaking.EventType.UPDATE_STATUS:
                        // 参加ユーザに変動があったときに返されます
                        Debug.Log ("[参加者]");
                        foreach (string joinedUserId in mmEvent.JoinedUserIds) {
                            Debug.Log (joinedUserId);
                        }
                        break;
                    case Gs2.Matchmaking.EventType.COMPLETE:
                        // マッチメイキングが成立したときに返されます
                        Debug.Log ("GS2-Realtime のゲームサーバ情報: " + gathering.Host + ":" + gathering.Port);
                        Debug.Log ("ゲームサーバとの通信に利用する暗号鍵: " + gathering.Secret);
                        Debug.Log ("マッチメイキングされた通信相手");
                        foreach (string joinedUserId in gathering.JoinedUserIds) {
                            Debug.Log (joinedUserId);
                        }
                        gathering = mmEvent.Gathering;
                        break;
                    case Gs2.Matchmaking.EventType.CANCEL_ACCEPT:
                        // マッチメイキングのキャンセルがサーバに受理されたときに返されます
                        break;
                    case Gs2.Matchmaking.EventType.FAILED:
                        // 何らかの理由によりマッチメイキングが失敗したときに返されます
                        Debug.Log ("失敗理由: " + mmEvent.Reason);
                        break;
                    }
                }
            },
            session);    // GS2 のログインセッション
    }
}

どちらの方式を採用しても同じように マッチメイキング機能を利用することが出来ます。

マッチメイキングが成立したら、 GS2-Realtime を利用して対戦や協力プレイの実装を進めることになります。