オンラインゲームを完成させるために必要な5つの条件
こんにちは!ジェイです。先日ずっと作っていたTPSオンラインゲームがやっと完成したので、その時に学んだオンラインゲーム制作を完成させるために必要な事を述べていきます。
ネットワークエンジン独自の特性を理解する
結論からいうとネットワークエンジンの独自の特性を理解する事です。オフラインゲームとオンラインゲームではまったく違う概念が必要になるからです。
- ネットワークに接続やロビーやルームの概念
- 通信や接続系の特殊なコールバック関数
- 所有権とマスタークライアント(ホスト)
- ネットワーク上でのオブジェクトの生成
- 同期の特性
上記の特性を理解する事がオンラインゲームを作る上で欠かせない要素になります。
ネットワークに接続やロビーやルームの概念
PhotonCloudの未接続状態から接続状態までの流れを図にしました。
未接続からロビー入室までの流れ
PhotonNetwork.autoJoinLobbyがfalseの場合

PhotonNetwork.autoJoinLobbyがtrueの場合

この図はPhotonCloudでのロビー入室の流れですが、MonobitEngineでもほぼ同じです。MonobitEngine.MonobitNetwork.autoJoinLobbyのプロパティがtrueかfalseで別れます。
呼ばれるイベント関数
void OnConnectedToPhoton()
最初の接続が確立したとき呼ばれるようです。
この関数が呼ばれたときには、まだPhotonの準備が整っていないようです。
接続確認には、後述のOnConnectedToMaster()
とOnJoinedLobby()
の方がいいみたいです。void OnConnectedToMaster()
マスターへの接続が確立し認証された際に呼ばれるようです。
Auto-Join Lobbyが有効な場合は、この関数は呼ばれません。void OnJoinedLobby()
マスターサーバーのロビーに入ったときに呼ばれるようです。
Auto-Join Lobbyが有効な場合は、接続後こちらが呼ばれます。void OnReceivedRoomListUpdate()
ロビー内のルームのリストが更新された際に呼ばれるようです。OnJoinedLobby()
が呼ばれた際に同時に呼ばれます。void OnFailedToConnectToPhoton( DisconnectCause cause )
サーバーに到達できず接続できない際に呼ばれるようです。void OnConnectionFail( DisconnectCause cause )
何かのせいで(接続が確立した後)接続失敗したときに呼ばれるようです。void OnPhotonMaxCccuReached()
同時接続可能数の制限に到達した場合に呼ばれるようです。void OnDisconnectedFromPhoton()
Photonサーバーから回線を切断した後で呼ばれるようです。
接続済みからルーム入室までの流れ

ルームを作成しようとした際の流れです。

ルームに入ろうとした際の流れです。JoinOrCreateRoom()
を使用する場合は、上記のルームを作成しようとする流れから入り、作成できなかった場合に以下の流れに入ります。

JoinRandomRoom()
を使用してルームに入ろうとした際の流れです。

最後に通信が切断される時の流れです。

呼ばれるイベント関数
スクリプトリファレンス参照
Photon Unity Networking: メインページ
void OnJoinedLobby()
マスターサーバーのロビーに入ったときに呼ばれるようです。void OnReceivedRoomListUpdate()
ロビー内のルームのリストが更新された際に呼ばれるようです。void OnCreatedRoom()
ルームを作成した際に呼ばれるようです。void OnJoinedRoom()
ルームに入った際に呼ばれるようです。void OnPhotonCreateRoomFailed( object[] codeAndMsg )
ルームの作成に失敗した際に呼ばれるようです。void OnPhotonJoinRoomFailed( object[] codeAndMsg )
ルームに入れなかった際に呼ばれるようです。void OnPhotonRandomJoinFailed( object[] codeAndMsg )
どのルームでもいいよといったにも関わらず、それでもルームに入れなかった際に呼ばれるようです。void OnPhotonCustomRoomPropertiesChanged( Hashtable propertiesThatChanged )
ルーム内のプロパティに変化があった際に呼ばれるようです。void OnPhotonPlayerPropertiesChanged( object[] playerAndUpdatedProps )
ルーム内のプレイヤーのプロパティに変化があった際に呼ばれるようです。void OnDisconnectedFromPhoton()
Photonサーバーから回線を切断した後で呼ばれるようです。
ここまでの流れはPhotonCloudでもMonobitEngineでもほとんど一緒なのでどちらか理解できれば接続→ロビー入室→ルーム入室までの理解は完璧です。
通信や接続系の特殊なコールバック関数
上記の呼ばれるイベント関数というのが、通信や接続系の特殊なコールバック関数です。暗記する必要はありませせんが、ほぼ定型文で使える事が多いので、さっと目を通しておくとよいでしょう。
所有権とマスタークライアント(ホスト)
所有権について
自分が生成したオブジョクトなら[photonView.isMine]がtrueそうでなければ、falseを返します。MonobitEngineでは[monobitView.isMine]で、このisMineで所有権の有無を確認できます。例えばキャラクターなど、所有権をチェックしないで動かすと関係ないキャラクターまで動いてしまうので、絶対に必要です。
マスタークライアント(ホスト)について
PhotonCloudではマスタークライアント、MonobitEngineではホストというのは、ルームに一番最初に入室した者の事で、ルーム内のプレイヤーをキックしたり、特別な権限が与えられた人の事です。
ネットワーク上でのオブジェクトの生成
Unityで通常のオブジェクトを生成する時にはInstantiateを使用します。ネットワーク上で同期するオブジェクトを生成するには、PhotonNetwork.InstantiateやMonobitNetwork.Instantiateを使います。これには生成するオブジェクトにPhotonViewやMonobitViewをアタッチしてResouceフォルダにPrefabを入れておく必要があります。この時に注意する点は以下の記事を参考にしてください。
同期の特性
PhotonCloudもMonobitEngineも同期には以下の3種類の方法があります。
- RPC(リモートプロシージャコール)での同期
- OnPhotonSerializeViewやOnMonobitSerializeViewでの同期
- カスタムプロパティでの同期
それぞれ特徴があって、簡単に説明するとRPCはその場で一瞬だけ同期したい処理をするのに適しています。SerializeViewは毎ループ必ず同期させる処理に適していますが、それだけ負荷が高いです。カスタムプロパティについては、ルームに紐づくルームプロパティとプレイヤーと紐づくプレイヤープロパティがあって、それぞれ同期させることができます。
ネットワークエンジン独自の特性を理解すればオンラインゲーム制作は難しくない
以上一気に説明したので、難しいと感じる人が多いかもしれませんが、途中入退出できる仕様のオンライン対戦できるTPSやFPS以外のゲームのような難しい仕様のゲーム以外は、Unityとネットワークエンジンを使えば、そこまで難しくなく誰でも作れるのでぜひチャレンジしてください!