Unityの公式チュートリアルに掲載されているマルチプレイヤーネットワーキングを勉強を進めている様子をお送りします。前回の記事はこちらからどうぞ
公式サイトのチュートリアルページ プレイヤーの動きをネットワーク化する
今回ステップはプレイヤーオブジェクトを制御するスクリプトを修正し、サーバーとクライアントでゲームオブジェクトとスクリプトがどのように処理されているかについて解説されています。
スクリプトコードにコメントを付けて内容を確認しました。今回のスクリプトのポイントは名前空間”using UnityEngine.Networking”の追加とクラス名の後にある”NetworkBehaviour”ですね。
using System.Collections; using System.Collections.Generic; using UnityEngine; // ネットワークコンポーネント関数を使用するため名前空間の追加 using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { // ゲーム実行中の繰り返し処理 void Update() { // プレイヤーが自分自身でない場合 if (!isLocalPlayer) { // 以降の処理を中断 return; } // 左右方向の入力値を変数 x に代入 var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; // 前後方向 入力値を変数 z に代入 var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; // オブジェクトの方向転換の制御 // (変数 xの値をオブジェクトのY軸回転に代入) transform.Rotate(0, x, 0); // オブジェクトの前進、後退の制御 // (変数 z の値をオブジェクトのZ座標に代入) transform.Translate(0, 0, z); } }
プレハブ Player の[Inspector]ウィンドウはコンポーネント NetworkTransform を追加してこのようになりました。
今回のステップではネットワーキング処理について次のように解説されています。
サーバーが 1 つにクライアントが 2 つある場合、つまり2人のプレイヤーでゲームをプレイする場合、サーバーとクライアントで同時処理されるプレイヤーゲームオブジェクトの数は 6になる。
詳しいことはこれから勉強を進めていきますが、このあたりが リアルタイムネットワークゲーム開発の難しさなのではないか?と感じました。
公式サイトのチュートリアルページ マルチプレイヤーの動きをテストする
今回のステップはネットワークマルチプレイヤーネットワーキングの動作確認です。
ゲーム実行中のエディタ側(クライアント)の状態がこちら。
そしてスタンドアロンプレイヤー側(ホスト)の状態がこちら。ちゃんと同期されています。
ただし、このステップの解説にもありますが、自分が操作するプレイヤーオブジェクトの動きがリモート側(クライアントで操作している場合はホスト)でカクカクしていてスムーズに移動できていません。
解説によると…
ネットワークを利用したマルチプレイヤーゲームにおいては、同期を完璧に行うことはできません。
ということで、ゲームは完全に同期されているように印象を与えるためのテクニックを別のチュートリアルで紹介すると書いてあるので、とりあえずこのままにしておきましょう。
公式サイトのチュートリアルページ ローカルプレイヤーの特定
今回はプレイヤーが自分のプレイヤーオブジェクトを識別できるようにするために、ホスト側とクライアント側でプレイヤーのマテリアルを変更する処理を追加します。
スクリプトコードにコメントを付けて内容を確認しました。
using System.Collections; using System.Collections.Generic; using UnityEngine; // ネットワークコンポーネント関数を使用するため名前空間の追加 using UnityEngine.Networking; public class PlayerController : NetworkBehaviour { // ゲーム実行中の繰り返し処理 void Update() { // プレイヤーが自分自身でない場合 if (!isLocalPlayer) { // 以降の処理を中断 return; } // 左右方向の入力値を変数 x に代入 var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f; // 前後方向 入力値を変数 z に代入 var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f; // オブジェクトの方向転換の制御 // (変数 xの値をオブジェクトのY軸回転に代入) transform.Rotate(0, x, 0); // オブジェクトの前進、後退の制御 // (変数 z の値をオブジェクトのZ座標に代入) transform.Translate(0, 0, z); } // ローカルプレイヤー時のゲームのスタート処理 public override void OnStartLocalPlayer() { // MeshRenderer コンポーネントを取得してマテリアルカラーを blue に設定 GetComponent<MeshRenderer>().material.color = Color.blue; } }
今回のステップの手順を終えた状態のエディタ側(クライアント)の再生画面はこちら。右側のオブジェクトが自分のプレイヤーオブジェクト。色が青色に変化しています。
そしてスタンドアロンプレイヤー(ホスト)を実行した画面がこちら。左側のオブジェクトが自分のプレイヤーオブジェクト。こちらもちゃんと色が青色に変化しています。