Edited at

モノビットエンジンでリアルタイム通信のオンラインゲームを作る:座標同期を行う

どうもnisokaです。

モノビットエンジン(MUN)を使ってリアルタイム通信ゲームを作ってみる!ということで。

これまでルームマッチングについて触れてきましたが、最低限のマッチング機能は一通りつくることができました。

今回からは簡単なミニゲームを使って、いよいよ実際にゲームの同期処理をつくっていきたいと思います。


はじめに

題材となるゲームは世界一シンプルなものが良いと思いまして「PingPongゲーム」にしました。

オンライン処理を行うことに焦点を絞ってまとめたいので、PingPongゲームの作り方などは今回は割愛したいと思います。

代わりにゲーム制作で参考にさせていただいたリンクページを貼らせていただきます。

参考:Unity 2D Pong Game in 20 Minutes

環境は以下の通りです

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

image1.PNG


やること

基本的なオフラインのPingPongゲームができている前提で話を進めます。

まず、各クライアントでパドルの移動の同期を取りたいと思います。

各プレイヤーが端末でパドルを動かしたときに、それぞれの端末画面でリアルタイムにパドルが動くということです。

これはモノビットエンジンを使えば比較的簡単に実装できます。


準備


MonobitView.csとMonobitTransfomView.csを追加する

image5.PNG

パドルの同期をとるためにはモノビットエンジンがパドルを監視する必要があります。

そのためにはまず、パドルに該当するコンポーネントにMonobitView.csをアタッチします。

image3.PNG

続いて、移動の同期をとるためにパドルに該当するコンポーネントにMonobitTransformView.csをアタッチします。


MonobitView.csとMonobitTransfomViewをアタッチする

image4.PNG

MonobitView.csのAdd Observed Componen List Colunボタンを押してListを増やします。

次にMonobitTransformView.csをドラックしてアタッチします。

(参考:MUN公式-MonobitTransformViewコンポーネント)


MonobitEngineを継承させる

最後にパドルに該当するスクリプトを変更し、以下のようにMonobitEngine.MonoBehaviourを継承させます。

これにより、モノビットエンジンが仲介役となってオブジェクトのTransform情報を他クライアントへ送る準備ができました。

using MonobitEngine;

public class Paddle : MonobitEngine.MonoBehaviour {
// クラスの処理
}


各クライアントにパドルを生成

if (MonobitNetwork.isHost)

{
// 球を(他クライアント上にも)生成
Ball ball = MonobitNetwork.Instantiate("Ball", Vector3.zero, Quaternion.identity, 0).GetComponent<Ball>();
}
// 自プレイヤーを(他クライアント上にも)生成
Paddle paddle = MonobitNetwork.Instantiate("Paddle", Vector3.zero, Quaternion.identity, 0).GetComponent<Paddle>();

上記のコードはあくまでサンプルですので、ご自身の環境に合わせて適宜変更お願いします。

まず、各クライアントはMonobitNetWork.Instantiateで自身のパドルを生成します。

MonobitNetwork.isHostで自身がホストかどうか取得できるます。

ゲストは自身のオブジェクトを生成して終了ですが、ホストの場合はついでにボールも生成します。

MonobitNetWork.Instantiateを使用することにより、他クライアント上にも同時に生成されます。

このとき生成したクライアントがそのオブジェクトの所有権を手にします。

所有権については後ほど後述しますが、簡単にいうと「自身のオブジェクトを動かせる権利」を指します。


isMineで自分だけのオブジェクトを操作する

このままだと、複数クライアントで動作させたときに不具合があることはすぐにわかります。

自身のパドルを動かそうとすると、相手プレイヤーのパドルまで同時に動いてします。

これは「全員のパドルを、プレイヤー全員で動かそうとしている」ことが原因です。

// パドルクラスUpdate

void Update()
{
if(monobitView.isMine)
{
// パドルの更新処理
}
}

そこで上記のようにmonobitView.isMineを使います。

各クライアントは自身が所有権を持つオブジェクトだけを更新し、他人に自身のオブジェクトを触らせないようにします。

参考:MUN公式「自身が所有権を持つプレイヤー」だけを動かすようにする


最後に

お疲れさまでした。

以上がモノビットエンジンを使って移動同期をとる手順紹介でした。

次回はボールを跳ね返す処理をやりたいと思います。