誰とでも

誰とでもマッチメイキングを GS2 SDK for Unity から利用する手順を解説します。

誰とでもマッチメイキング とは

GS2-Matchmaking が提供するマッチメイキング方式の中で最もシンプルなマッチメイキングです。

無条件で対戦・協力プレイ相手を探す際に利用できる仕組みで、名前の通り誰でもいいのでマッチメイキングされます。

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

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

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

../../../../_images/step-00012.png

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

../../../../_images/step-00022.png

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

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

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

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

../../../../_images/step-00031.png

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

../../../../_images/step-00041.png

マッチメイキングの名前をつけて、種類に『誰とでも』を指定します。

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

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

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

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

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

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

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

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

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

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

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

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

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

マッチメイキングを開始する

gs2.Matchmaking.Anybody.Start() でマッチメイキングを開始します。

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

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

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

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

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

実装サンプル

イベントハンドラ方式

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-0001";

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

    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 (StartMatchmaking ());
    }

    IEnumerator StartMatchmaking() {
        // マッチメイキングを開始する
        Gs2.Matchmaking.AnybodyMatchmakingConfig config =
            new Gs2.Matchmaking.AnybodyMatchmakingConfig ()
                .MatchmakingName (MATCHMAKING_NAME)        // GS2-Matchmaking に作成したマッチメイキング名
                .Handler (new EventHandler());            // イベントハンドラ
        gs2.Matchmaking.Anybody.Start (session, config);
        started = true;
    }

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

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

public class EventHandler : Gs2.Matchmaking.AutoMatchmakingEventHandler
{
    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-0001";

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

    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 (StartMatchmaking ());
    }

    IEnumerator StartMatchmaking() {
        // マッチメイキングを開始する
        Gs2.Matchmaking.AnybodyMatchmakingConfig config =
            new Gs2.Matchmaking.AnybodyMatchmakingConfig ()
                .MatchmakingName (MATCHMAKING_NAME);        // GS2-Matchmaking に作成したマッチメイキング名
        gs2.Matchmaking.Anybody.Start (session, config);
        started = true;
    }

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

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

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

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