UnrealEngine/覚書/ネットワークゲームを作る


いきなりハードル高いかもしれないがネットワークゲームを作ってみる。
まずはキャラ2体が自由に動き回るだけの形を目指そう。
とりあえずここを参考に進めてみる。

最初はシングルプレイ用のゲームを作ればいいよみたいなこと書いてあるのでその通り進めよう。

レベルを作る

まずはBSPからただの板を作成。
サイズとかテクスチャとかは適当に。
Player Startとかも作っておく。

キャラを作る

TPS用のキャラでいいかな。
このへんの前半部分を再度行った上で、アニメーションは適当に設定しておく。

ゲームモードを作るのも忘れずに。

とりあえず動かす

あとはここの通りにプレイヤー数を設定して起動してみる。

これだけでキャラが2体自由に動く物はでき上がる。
すごい簡単。

全てのノードで共有されるアクタを作る

これだけでは何もならないので、ボールでも置いてノード間で共有してみる。
このページを参考にした。

しかしブループリントからアクタを作成し、物理挙動付きのSphereを付けるも位置情報が同期されない。
どうやら物理挙動を付けた時に移動するのはアクタではなくその配下のコンポーネント(ここではsphere)のようなので、アクタ自体のTransformが同期されても意味が無いのだと思われる。

解決策としてサーバー側は毎フレームアクタのロケーションをボールの位置に変更。
クライアント側は逆にボールの位置をアクタのロケーションに変更する。
画像だとこういう感じ。
ballsync01.png

強制的に位置情報を更新しているから少し物理挙動がおかしい感じか?
とりあえずぱっと見は同期が取れているようなので一旦これで進めよう。

ジョグの速度とアニメーションが同期されない

ボールを作る前には気付かなかったが以下の状態が発生していた。
  • サーバー側のキャラクターが走った場合にクライアント側ではジョグアニメーションに遷移しない
    (つまりクライアント側の画面ではサーバー側のキャラが歩きモーションのまま高速に移動している)
  • クライアント側でキャラを走らせた場合にアニメーションは走るモーションに変わるのに速度は歩く速度のまま変わらない

ここから予測できることは
  • 移動(Transformの変更)に関してはサーバーで計算した物を各クライアントに配信して反映させている
  • アニメーションの遷移は各クライアントで管理し、独自に反映させている
  • 速度やアニメーションを遷移させるためのフラグ(変数)が共有されていない
ということ。

速度に関してはキャラクターブループリントのフラグの上げ下げで、アニメーションに関してはアニメーションブループリントのフラグの上げ下げで変更しているので、そのフラグの状態を同期すれば良さそうだ。
その方法はここに書いてあるのでまずはその通りやってみることにする。

キャラクター、アニメーションの全ての変数に対してRepNotifyを設定してみたところ、サーバー側のアニメーションがクライアント側に反映されるようにはなったが、クライアントの速度は変化しないという結果だった。
移動量の計算がサーバー側で行われているのであれば、クライアント側で立っているJogフラグがサーバー側では立っていないということだ。
キャラクターブループリントのフラグはキー入力で上げ下げしているので、ここから予測できることはキー入力の情報はサーバー側に送信されていないということ。

確証を得るためにブループリントのデバッグを見てみると、CharacterNNの様な名前でキャラクターが4つ選択できる状態だった。
調べてみたところ、これはそれぞれNNが若い順に以下の物であることも分かった。

  • サーバー側のサーバーキャラ
  • サーバー側のクライアントキャラ
  • クライアント側のクライアントキャラ
  • クライアント側のサーバーキャラ

今残っている問題はクライアントキャラの移動速度が、Jogボタンを押しても歩行時のまま変化しないということ。
この事実と、先程立てた「Transformの変更はサーバー側で計算している」という仮説を元にすると、まず調べなければならないのはサーバー側のクライアントキャラでどういう処理が走っているかだ。
で、見てみるとそもそもサーバー側のクライアントキャラにおいてはブループリントでは何も処理が走っていないようだった。
そして次にクライアント側のクライアントキャラを見てみると、今度はちゃんと処理が走っていてフラグも変化している。
ということはやはりクライアント側で変更したフラグがサーバー側に反映されないことが問題のようだ。

このページにうっすら書かれているが
クライアントからサーバーへデータを送信する方法は、「Events」セクションを参照してください。
とのことなので同じページに記載されているイベントのレプリケーションを使う。

まずカスタムイベントの追加をする必要があるので、こちらに書いてあるように、キャラクターブループリント内にカスタムイベントを作成する。

イベントはインプットを取った後でフラグをセットする前の箇所に配置する。
PressedとReleasedに対してそれぞれ作る必要があるので、とりあえずEvJogPressedとEvJogReleasedという名前で作っておく。様子見のために一旦グラフはサーバーで実行にしておこう。
そしてインプットアクションJogの後にそれぞれのカスタムイベントを実行するように設定。

つまりこの状態から
charsyncBefore.png

こうするということ。
charsyncAfter.png

設定を行ったところ、無事フラグがサーバー側にも反映されて移動速度が変化するようになった。
なおアニメーションのフラグがキャラクターのフラグを元に変化するようになっている場合、この設定をすることによってアニメーションのフラグを同期する必要は無くなる。
なぜならばアニメーションは各クライアントで勝手に計算して遷移するようになっているからだ。

つまりまとめると、ネットワークゲームでキャラクターを同期する場合には

  • キャラクターブループリント内で変数をセットする箇所をサーバー実行のカスタムイベントにする
    (上記画像のようにする)
  • 変数をレプリケーションする設定にする
  • (アニメーションのフラグがキャラクターのフラグから取得されている場合においては)アニメーションのフラグをレプリケーション設定する必要は無い

という感じのようだ。

  • 最終更新:2016-02-23 11:20:06

このWIKIを編集するにはパスワード入力が必要です

認証パスワード