🌐

Photon Fusionを用いたオンラインゲームの制作で気になったことPart2~インゲーム設計編~

に公開

今回は、前回に引き続きPhoton Fusionを用いたオンラインマルチプレイゲーム開発で気になったことや躓いた所をまとめようと思います。

前提

今回作るゲームは最大四人でマッチングするオンラインマルチプレイゲームです。Playerの中からランダムに一人が鬼として選ばれ、鬼になったPlayerは他のPlayerを攻撃して気絶させることで鬼をそのPlayerに渡すことができます。一定時間後に鬼だったPlayerは敗北となり、残りのPlayerは他Playerを気絶させたときやステージ内のギミックを使用することによって得られるポイントによって順位が決まります。

インゲームシステムの設計

前回に引き続き私の担当部分であるInGameのシステム部分についてお話ししたいと思います。早い話、現在のクラス図を見ていただきたいと思います。

前回からかなり更新がかかっているので要点をまとめて解説します。

①InGameManagerとPlayerの関係について

端的に言うと、InGameManagerがPlayerを生成し、生成時に処理(OnPlayerKilled)を登録する設計にしました。Playerの生成までしてしまうとInGameManagerがスーパークラスになりすぎてしまうかなとも思いましたが、Player死亡時の処理をSpawn時に登録する際にPlayerのインスタンスが欲しかったので、今回の実装に至りました。

②Rankingデータの保持、受け渡しについて

今回のゲームでは前提で話したようなルールにのっとったランキングをResultシーンにて表示させます。今回の実装で気をつけなければいけない点が二点あって、

  1. RankingデータをInGameシーンからResultシーンに至るまで保持しなければいけない
  2. Rankingデータを各クライアントにも伝達しなければいけない

という点です。以上の二点を解決するために、

  1. Rankingデータを保持しておく別のシングルトンクラス(RunkingDataHolder)を用意する
  2. 各クライアントのRunkingDataHolderにRanking情報をRPCで伝達する

という方法をとることにしました。RPCって何ぞやという方は以下の公式リファレンス等を参考にしてください。

ざっくり言うとRPC(Remote Procedure Call)という機能を使うとあるプレイヤーが実行した関数をほかのプレイヤーでも実行するといったことができるようになります。NetWorked属性をつけたり同期させるのと何が違うの?という点ですが、意味合い的にはほとんど変わりません。ただ、NetWorkedプロパティに関しては状態を継続的に監視することに優れており、RPCは命令として決まったタイミングで送れるという違いがありますので、ユースケースに合わせて選択するのが良いと思います。

またその他にもGameStateを用意してゲームフローを外部から参照できるようにしたり、ServiceLocatorへの登録を行ったりもしています。ただInGameManager自体がかなりコード量が多くなってしまい見づらくなってしまったので、現在ImtStateMachineというステートマシンを使ってクラスを分割させていく予定です。こちらについてはまた別の機会にお話しできればと思います。

まとめ

今回はインゲーム部分の設計についてお話ししました。今後は実際にPlayerがインタラクトするオブジェクトの制作を進めていくのでAnimation等の同期や入力権限についてなどの話も出来たらいいなと思っています。最後までお読みいただき、ありがとうございました。

Discussion