Unityの公式チュートリアルに掲載されているマルチプレイヤーネットワーキングを勉強を進めている様子をお送りします。前回の記事はこちらからどうぞ
シューティング(シングルプレイヤー)
公式サイトのチュートリアルページ シューティング(シングルプレイヤー)
今回ステップは非ネットワークの状態でプレイヤーにシューティング機能を追加します。
弾のプレハブを作成する
- 基本オブジェクト Sphere を作成して名前を “Bullet” に変更
- オブジェクト Sphere の Transform > Scaleを (X 0.2, Y 0.2, Z 0.2) に変更
- オブジェクト Sphere に Physics > Rigidbody コンポーネントを追加
- Rigidbody コンポーネントの Use Gravity チェックボックスを false に設定
- オブジェクト Bullet を Project ウィンドウにドラッグし、プレハブを作成
- ゲームオブジェクト Bullet をシーンから削除
- シーンを保存
プレハブ Bullet の[Inspector]ウィンドウはこのようになりました。

スクリプト PlayerController に弾を発射する処理を追加する
次は弾を発射するためにスクリプト PlayerController を修正します。
- スクリプト PlayerController を開く
- Bullet プレハブを格納するためのパブリックフィールドを 1 つ追加
- Bullet Spawn を格納するためのパブリックフィールドを 1 つ追加
- Update 関数内に入力処理を追加
- 弾を発射するための関数 Fire を追加
- スクリプトを保存
出来上がったスクリプトコードにコメントを付けて内容を確認しました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// ネットワークコンポーネント関数を使用するため名前空間の追加
using UnityEngine.Networking;
public class PlayerController : NetworkBehaviour
{
// 弾のプレハブを格納する変数
public GameObject bulletPrefab;
//弾のプレハブを発生するオブジェクトの Transform を格納する変数
public Transform bulletSpawn;
// ゲーム実行中の繰り返し処理
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);
// Space キーの入力があったら関数 Fire() を実行する
if (Input.GetKeyDown(KeyCode.Space))
{
Fire();
}
}
// 弾を発射する処理
void Fire()
{
// プレハブ Bullet から インスタンス Bullet を生成する
// 変数 bullet にインスタンスを格納
var bullet = (GameObject)Instantiate(
// 変数 bulletPrefab に格納されたオブジェクトを
bulletPrefab,
// 変数 bulletSpawn に格納された Transform の座標で
bulletSpawn.position,
// 変数 bulletSpawn に格納された Transform の角度で
bulletSpawn.rotation);
// 弾の速度を増加させる
//(Rigidbody コンポーネントを取得して速度6倍で前方に移動する)
bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 6;
// 2秒後に弾を破壊する
Destroy(bullet, 2.0f);
}
// ローカルプレイヤー時のゲームのスタート処理
public override void OnStartLocalPlayer()
{
// MeshRenderer コンポーネントを取得してマテリアルカラーを blue に設定
GetComponent<MeshRenderer>().material.color = Color.blue;
}
}
プレハブ Player の[Inspector]ウィンドウでスクリプトコンポーネントを見るとこのように変数フィールドが追加されました。

プレイヤーオブジェクトに銃を追加する
プレイヤーオブジェクトに弾を発射するための銃を作成します。
- プレハブ Player を編集するために、[Hierarchy]ウィンドウにドラッグ
- 基本オブジェクトの Cylinder を作成して名前を “Gun” に変更
- オブジェクト Gun をオブジェクト Player の子にする
- オブジェクト Gun 選択して Capsule Collider コンポーネントを削除
- Transform の Position を X 0.5, Y 0.0, Z 0.5 に設定
- Transform の Rotation を X 90.0, Y 0.0, Z 0.0) に設定
- Transform の Scale をX 0.25, Y 0.5, Z 0.25) に設定
- Material を Black に設定
Gun の[Inspector]ウィンドウでTransform のパラメーターはこのようになっています。

プレイヤーオブジェクトに弾発射用オブジェクトを追加する
- 空のオブジェクトを 1 つ作成して名前を “Bullet Spawn” に変更
- オブジェクト Bullet Spawn をオブジェクト Player の子にする
- Bullet Spawn の Position をX 0.5, Y 0.0, Z 1.0) に設定
- オブジェクト Player が選択された状態で、[Inspector]ウィンドウ > Prefab > Apply クリック
- シーンからオブジェクト Player を削除
- シーンを保存
PlayerController コンポーネントの設定
修正したスクリプト PlayerController で作成した変数フィールがコンポーネントに表示されているので必要なオブジェクトを割り当てます。
- プレハブ Player を選択
- PlayerController コンポーネントの Bullet Prefab フィールドに Bullet プレハブを追加
- PlayerMovement コンポーネントの BulletSpawn フィールドに Bullet Spawn を追加
- プロジェクトを保存
Bullet Spawn を ドラッグ&ドロップでフィールドに割り当てるには、[Project]ウィンドウのプレハブ Playerの階層を開いて選択すればOKです。

プレハブ Player の[Inspector]ウィンドウでスクリプトコンポーネントを見るとこのようになりました。

動作確認
ここまでの手順を動作確認するステップです。
- スタンドアロンのアプリケーションとして[Build and Run]をクリック
- ビルドファイルが完成するとゲームが実行される
- ゲーム内 UI から [LAN Host(H)] ボタンをクリックしてホストとしてゲームを開始
- Player ゲームオブジェクトを動かして動作を確認
- エディタ側でPlay モードを開始
- ゲーム内 UI から [LAN Client] ボタンをクリックしてクライアントとしてホストに接続
- スタンドアロンプレイヤーを終了し、エディタ側でPlay モードを終了
このステップを終えてゲームを実行。今回はビルドしたゲームを2つ実行してウィンドウを並べました。解説に書いてある通り、ローカル(ホスト)となる自分のゲーム画面(下図では左側)では発射した弾が表示されますが、右側のリモート(クライアント)画面では表示されません。

次のステップでリモート側でも自分の発射した弾が表示されるようにネットワークに対応させる手順になりますが、今回はここまでにしたいと思います。