Unity:プレイヤーの体力をネットワーク化する~マルチプレイヤーネットワーキングのチュートリアルに挑戦

スポンサーリンク

Unityの公式チュートリアルに掲載されているマルチプレイヤーネットワーキングを勉強を進めている様子をお送りします。前回の記事はこちらからどうぞ

プレイヤーの体力をネットワーク化する

公式サイトのチュートリアルページ プレイヤーの体力をネットワーク化する

今回は体力値の変更をサーバーで行い、その後クライアントで同期するように改造します。

スクリプトHealthの修正

体力値の変更をサーバー上のみで行うようにスクリプトを修正します。

  1. Health スクリプトを開く
  2. 名前空間 UnityEngine.Networking を追加
  3. スクリプトを、NetworkBehaviour から派生するように変更
  4. 変数 currentHealth を作成して [SyncVar]属性を付ける
  5. ダメージがサーバー上のみで適用されるように、関数 TakeDamage に isServer のチェックを追加
  6. スクリプトを保存

修正したスクリプトのコードにコメントを加えたものがこちら。

動作確認

  1. シーンをスタンドアロンのアプリケーションとして Build and Run を実行
  2. ゲーム内 UI から[Host]ボタンをクリックしてゲームをホストとして開始
  3. プレイヤーゲームオブジェクトを動かす
  4. Unity に戻ってPlay モードを開始
  5. ゲーム内 UI から[LAN Client]ボタンをクリックしてクライアントとしてホストに接続
  6. スタンドアロン プレイヤーを終了
  7. Unity に戻ってPlay モードを終了

このステップを終えてゲームを実行。ビルドしたゲームを2つ実行してウィンドウを並べました。画面左のホスト(サーバー&クライアント)のみ体力ゲージが処理されています。

スクリプト Health の修正

体力値ゲージの RectTransform を他のクライアントでも同期するようにスクリプトを修正します。

  1. Health スクリプトを開く
  2. Healthbar を変化させるコードを、新規関数 OnChangeHealth 内に移動
  3. currentHealth の SyncVar 属性内に、新規関数 OnChangeHealth へのフックを設定
  4. スクリプトを保存

修正したスクリプトのコードにコメントを加えたものがこちら。

チュートリアルの解説部分で書かれている 関数 void OnChangeHealthの引数名が、関数部分だけ書かれている部分では下記の通り記述されています。

void OnChangeHealth (int currentHealth)
{
healthBar.sizeDelta = new Vector2(health, currentHealth.sizeDelta.y);
}

一方、スクリプト Health の全コードが書かれている部分では void OnChangeHealth (int health) と記述されていたので、しばらく???となりましたが、意味を考えると Health の全コードが書かれている
void OnChangeHealth (int health) の方が正しいと判断しました。

動作確認

  1. シーンをスタンドアロンのアプリケーションとして Build and Run を実行
  2. ゲーム内 UI から[Host]ボタンをクリックしてゲームをホストとして開始
  3. プレイヤーゲームオブジェクトを動かす
  4. Unity に戻ってPlay モードを開始
  5. ゲーム内 UI から[LAN Client]ボタンをクリックしてクライアントとしてホストに接続
  6. スタンドアロン プレイヤーを終了
  7. Unity に戻ってPlay モードを終了

このステップを終えてゲームを実行。ビルドしたゲームを2つ実行してウィンドウを並べました。

画面左のホスト(サーバー&クライアント)側、画面右のクライアント側のどちらも外力ゲージが変化して同期されるようになりました。

今回のポイントはこの部分ですね。

ステート同期(State Synchronization)の為のもうひとつのツール、SyncVar フック の登場です。SyncVar フックは、関数を SyncVar と結び付けます。これらの関数は、SyncVar の値が変わるとサーバーおよび全てのクライアント上で呼び出されます。

ダメージ処理はサーバー側だけで行い、その変数の変化に合わせてクライアント側で体力ゲージの処理を行うといういうのはうまくできているな~と思いました。