見出し画像

Netcode for GameObjectsの動作確認

本記事のゴール

  • Netcode for GameObjectsを利用してUnityChanを同期させて動かすサンプルを作成します。

動機

  • 多人数で仮想空間を共有したい。(できるだけ簡単な方法で)

筆者環境

  • Macbook Air

  • macOS Monterey 12.5 Apple M1

  • Unity 2021.3.01f

参考

Netcode for GameObjectsを使ってみよう - Unityステーションhttps://www.youtube.com/watch?v=GRUtGLL8iMQ&t=1791

準備

UnityChanの導入

以下のアセットストアのリンクからMyAssetsに追加します。

Netcode for GameObjectsの導入

Package Manager > Add package by name…で以下の名前を入れます。

  • com.unity.netcode.gameobjects

手順

  1. Network Managerの設定

  2. ゲーム画面上でホスト・クライアント入室ボタンの作成

  3. 同期オブジェクトの設定

  4. Network ManagerのPlayerに同期オブジェクトを設定

  5. サーバ・クライアント間の入力情報の同期処理

1. Network Managerの設定

空オブジェクトを作成し、Network Managerのスクリプトを適用して、各種パラメータを入力します。

今回のサンプル動作では、Network Transportのパラメータに「NetworkManager (Unity Transport)」を選択する設定だけをします。

2. ゲーム画面上でホスト・クライアント入室ボタンの作成

ゲームを始める時にホストかクライアントかを決めて開始します。この時に必要なボタンとボタンの処理を作成します。

2.1. ボタンの作成
「Host」というボタンと「Client」というボタンを作成します。

2.2. ボタンの処理の作成

NetworkManagerのStartHost(), StartClient()を呼び出せるpublic関数をもったスクリプト(以下NetworkUIクラス)を作成して空オブジェクトに適用します。
ホスト入室ボタンのイベントにはNetworkUI.StartHost()を、クライアント入室ボタンのイベントにはNetworkUI.StartClient()を適用します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NetworkUI : MonoBehaviour
{
    public void StartHost()
    {
        Unity.Netcode.NetworkManager.Singleton.StartHost();
    }

    public void StartClient()
    {
        Unity.Netcode.NetworkManager.Singleton.StartClient();
    }
}

3. 同期オブジェクトの設定

同期させたいGameObject(今回はUnityChan)に同期用スクリプトを適用します。同期用のスクリプトとしては以下のようなものがあります。

  • Network Object: 同期オブジェクト設定

  • Network Transform: 位置の同期

  • Network Animator: アニメーションの同期

上記以外にもありますが、これ以上の説明は割愛します。

4. Network ManagerのPlayerに同期オブジェクトを設定

Network ManagerのPlayer Prefabに同期オブジェクトの設定を行なったUnityChanを設定します。

5. サーバ・クライアント間の入力情報の同期処理

Playerオブジェクトの入力・動作処理を行うスクリプトに対して以下の修正を行います。

5.1. 継承クラスをUnity.Netcode.NetworkBehaviourに変更

// 継承を MonoBehaviour -> Unity.Netcode.NetworkBehaviour に変更
public class UnityChanControlScriptWithRgidBody : Unity.Netcode.NetworkBehaviour
{
  ...
}

5.2. ServerRpcの作成

[Unity.Netcode.ServerRpc]
private void SetServerMoveInputServerRpc(float x, float y)
{
    this.moveInput = new Vector2(x, y);
}

5.3. 入力処理をServerRpcに置き換え
※ 本手法はサーバ側に全て処理を任せるサンプルです。遅延の発生を考慮して、Ownerの処理を優先する方法もありますが、割愛します。

入力処理をOwnerの場合のみ(this.IsOwner== trueの場合のみ)にして、入力値でServerRpcを呼び出すようにします。


if (this.IsOwner)
{
    float h = Input.GetAxis ("Horizontal");				// 入力デバイスの水平軸をhで定義
    float v = Input.GetAxis ("Vertical");	
    SetServerMoveInputServerRpc(h, v);
}

動作量を反映する処理をServerの場合のみ(this.IsServer == trueの場合のみ)にします。

if (this.IsServer)
{
    // vを利用していたのをmoveInput.yに変更する
    anim.SetFloat ("Speed", moveInput.y);
    // hを利用していたのをmoveInput.xに変更する
    anim.SetFloat ("Direction", moveInput.x);	
		
    ...(同様の作業の繰り返し)
}

動作確認

上記設定が全てできたら動作確認をします。

複数人で動作を確認するため、Unityエディタ上では完結しないため、片方をビルドしたもので動作させる。

片方はホスト入室して、もう片方はクライアント入室をするとちゃんと同期しているのがわかります。

この記事が気に入ったらサポートをしてみませんか?