Categories: Unity

Unity:マルチプレイヤーシューティングを追加する~マルチプレイヤーネットワーキングのチュートリアルに挑戦

Unityの公式チュートリアル「マルチプレイヤーネットワーキング」の実習の模様をお送りしております。前回の記事はこちらからどうぞ

マルチプレイヤーシューティングを追加する

公式サイトのチュートリアルページ マルチプレイヤーシューティングを追加する

プレハブ Bullet にネットワーキングコンポーネントを追加する

  1. [Project]ウィンドウ > プレハブ Bullet を選択
  2. Network > NetworkIdentity コンポーネントを追加
  3. Network > NetworkTransform コンポーネントを追加
  4. NetworkTransform コンポーネント > Network Send Rate を 0 に設定
  5. [Hierarchy]ウィンドウ > NetworkManager を選択
  6. NetworkManager コンポーネント > Spawn Info ドロップダウンメニューを開く
  7. Registered Spawnable Prefabs のリストで[+]ボタンで新しい行を追加
  8. Registered Spawnable Prefabs リストに追加した行にプレハブ Bullet を追加

プレハブ Bullet の[Inspector]ウィンドウでコンポーネントを確認するとはこのようになっています。(表示は折りたたんだ状態)

スクリプト PlayerController を編集

弾を発射する処理をクライアントから呼び出してサーバーで実行するようにネットワークコマンドに変更します。

  1. 編集用に PlayerController スクリプトを開く
  2. Fire 関数に [Command] 属性を追加して、ネットワークコマンドにする
  3. 関数名にプレフィックス “Cmd” を追加して “CmdFire” に変更
  4. Update 内で呼び出される関数の名前を CmdFire に変更
  5. 弾を生成させるために NetworkServer.Spawn 関数を追加
  6. スクリプト PlayerController を保存

スクリプトコードにコメントを付けて内容を確認しました。黄色マーカー部分が今回の変更箇所です。

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))
        {
            CmdFire();
        }
    }

    // 弾を発射する処理
    //(ネットワークコマンド:クライアントから呼び出しサーバーで実行)
    [Command]
    void CmdFire()
    {
        // プレハブ 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;

        // クライアント上に弾を生成する
        NetworkServer.Spawn(bullet);

        // 2秒後に弾を破壊する
        Destroy(bullet, 2.0f);
    }

    // ローカルプレイヤー時のゲームのスタート処理
    public override void OnStartLocalPlayer()
    {
        // MeshRenderer コンポーネントを取得してマテリアルカラーを blue に設定
        GetComponent<MeshRenderer>().material.color = Color.blue;
    }
}

動作確認

  1. Build Settingsウィンドウを開き、スタンドアロンのアプリケーションとして[Build and Run]をクリック
  2. ビルドファイルが完成するとゲームが実行される
  3. ゲーム内 UI から [LAN Host ] ボタンをクリックしてホストとして開始
  4. プレイヤーオブジェクトを操作テスト
  5. エディタ側でPlay モードを開始
  6. ゲーム内 UI から [LAN Client] ボタンをクリックしてクライアントとしてホストに接続
  7. プレイヤーオブジェクトを操作テスト
  8. スタンドアロンプレイヤーを終了、エディタ側のPlay モードを終了

このステップを終えてゲームを実行。ビルドしたゲームを2つ実行してウィンドウを並べました。ホストになる自分のゲーム画面(下図では左側)で発射した弾が、右側のクライアント画面でも表示されるようになりました。

チュートリアルに書いてある通り、弾のゲームオブジェクトは相手プレイヤーに当たると跳ね返るだけで、相手プレイヤーに対して影響は与えていませんね。

corevale