Edited at

モノビットエンジン版 RPCメッセージを使いパラメータ同期をおこなう


はじめに

どうもnisokaです。

今回はモノビットエンジンを使ってRPCメッセージによるパラメータ同期を行いたいとおもいます。

環境は以下の通りです

win10 64bit, Unity2018.3.3f1, Monobit Unity Networking2.0 v2.6


やること


  • ルームマッチングシーン⇔ゲームシーン間の画面遷移

  • 得点スコアのパラメータ同期


RPCメッセージについて

RPC(Remote Procedure Call)遠隔手続き呼び出しとはネットワーク越しに別のコンピュータ上の関数を呼び出すことをいいます。情報を飛ばし合うオンラインゲームを作る上では必要になる機能です。

実はMUNにも、同様のRPCメッセージ機能が用意されていますのでこれを使っていきます。

RPCの使用条件はMonobitViewアタッチ・MonobitEngine.MonoBehaviour継承・ルーム入室状態です。

以下、RPC記述例です。

// 受信メソッド

[MunRPC]
void RecvExampleFunc(int id, string name)
{
Debug.Log("番号:" + id + ",名前: " + name);
}
// 送信メソッド
monobitView.RPC("RecvExampleFunc", MonobitEngine.MonobitTargets.Others, id, name);

送信者自身以外のルーム内プレイヤーに対し、サーバを介して送信します。

(参考:Mun公式-RPC(Remote Procedure Call))


シーン遷移を通知

ルームマッチングシーンからメインゲームシーンへ遷移します。

現状だとホストだけが遷移してしまい、他プレイヤーが置いてけぼりになります。

そこで、ホストがプレイヤー全員に遷移すること通知してあげます。

ルームマッチングシーンで必要な人数が集まりマッチングを終えると、ホストだけにゲームスタートボタンが現れます。

そのボタンを押すことでゲームシーンへ遷移するという実装にします。


RPC送信メソッド

if (MonobitNetwork.room.playerCount >= MonobitNetwork.room.maxPlayers)

{
if (MonobitNetwork.inRoom && MonobitNetwork.isHost)
{
if (GUILayout.Button("Game Start"))
{
MonobitNetwork.room.open = false;

monobitView.RPC("RecvGameStart", MonobitEngine.MonobitTargets.All, null);
}
}
}

MonobitNetwork.room.playerCountは現在のルーム入室人数、

MonobitNetwork.room.maxPlayersはルーム最大入室可能人数です。

MonobitNetwork.inRoomはルームに入室しているかどうかです。

MonobitNetwork.room.open = falseでホストはルームをクローズして入室不可にします。

最後にmonobitView.RPC("RecvGameStart", MonobitEngine.MonobitTargets.All, null);ホスト自身を含むプレイヤー全員に対してゲーム開始を告げます。


RPC受信メソッド

[MunRPC]

void RecvGameStart()
{
SceneManager.LoadScene("InGameScene");
}

ホスト含め全プレイヤーがメッセージを受け取るとSceneManager.LoadLevel("InGameScene");を呼ばれ、順次InGameSceneに遷移します。


RPCを使わないScene遷移

MonobitNetwork.autoSyncScene = true;

MonobitNetwork.LoadLevel("InGameScene");

MUNにはMonobitNetwork.LoadLevel()というメソッドがあり、これを使うことでRPCのコーディング無しに上記を実現できます。

MonobitNetwork.LoadLevel()単体ではSceneManager.LoadScene()と動作の違いはありませんが、

MonobitNetwork.autoSyncSceneというパラメータをtrueにすることで、同一ルームのホストがMonobitNetwork.LoadLevel()によるシーン遷移を行ったとき、ホストに合わせてルーム内の全クライアントが同一のシーン遷移を行います。

これにより、RPCのコーディングせずに読み込むゲームシーンを同期できます。


スコアのパラメータ同期

スコアが変化した場合、ホストだけがスコア計算を行います。

その結果をゲストだけが受け取り、ゲストはそれを自身のスコアへ反映するというプロセスです。

ホスト側ではスコアが変化したときに呼び出す関数を定義します。

RPCの引数には計算後の結果を渡します。

public void ChangeScore(int num)

{
if(MonobitNetwork.isHost)
{
this.score += num;
monobitView.RPC("RecvSyncScore", MonobitTargets.Others, this.score);
}
}

続いて、ゲスト側では計算結果を反映する関数を定義します。

[MunRPC]

void RecvSyncScore(int score)
{
this.score = score;
}


最後に

簡潔にMunRPCの使い方を紹介しました。

考え方さえ分かってしまえば、手順を踏み、用意されているメソッドを呼び出すだけなのですぐに実装できるかとおもいます。

(私はオンラインの考え方がなかなか理解できず困り果てました)


参考リンク