Multiplayer-VR-First

はじめに

Unity Japan が公開している「Netcode for GameObjectsを使ってみよう - Unityステーション」を手順通りにやってみた。

Relay サーバを使う前までの内容まとめなど。

このリポジトリの Scene/first の内容。

インストール

デモキャラの設定

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

public class PlayerMove_KB : Unity.Netcode.NetworkBehaviour
{
  private float speed = 1.0f;
  private Vector3 moveInput;

  void Update()
  {
    if(this.IsOwner){
      float x = Input.GetAxis("Horizontal");
      float z = Input.GetAxis("Vertical");
      moveInput = new Vector3(x, 0, z);
      Move();
    }
    
    // 復帰処理
    if(transform.position.y < -10)
    {
      transform.position = new Vector3(Random.Range(-5, 5), 0, Random.Range(-5, 5));
    }
  }

  private void Move()
  {
    var delta = new Vector3(moveInput.x, 0, moveInput.z);

    transform.position += delta * speed * Time.deltaTime;
  }
}

NetworkManager の追加

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

Host/Client のUI追加

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

動作確認

位置の同期 (サーバ→ホスト)

移動の操作権限の管理

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

public class PlayerMove_KB : Unity.Netcode.NetworkBehaviour
{
  private float speed = 1.0f;
  private Vector3 moveInput;

  void Update()
  {
    if(this.IsOwner){
      float x = Input.GetAxis("Horizontal");
      float z = Input.GetAxis("Vertical");
      moveInput = new Vector3(x, 0, z);
      Move();
    
      // 復帰処理
      if(transform.position.y < -10)
      {
        transform.position = new Vector3(Random.Range(-5, 5), 0, Random.Range(-5, 5));
      }
    }
  }

  private void Move()
  {
    var delta = new Vector3(moveInput.x, 0, moveInput.z);

    transform.position += delta * speed * Time.deltaTime;
  }
}

位置の同期 (クライアント→サーバ)

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

public class PlayerMove_KB : Unity.Netcode.NetworkBehaviour
{
  private float speed = 1.0f;
  private Vector3 moveInput;

  // Start is called before the first frame update
  void Start()
  {
      
  }

  // Update is called once per frame
  void Update()
  {
    if(this.IsOwner){
      float x = Input.GetAxis("Horizontal");
      float z = Input.GetAxis("Vertical");
      MoveServerRpc(x, z);
    }

    if(this.IsServer){
      Move();
    
      // 復帰処理
      if(transform.position.y < -10)
      {
        transform.position = new Vector3(Random.Range(-5, 5), 0, Random.Range(-5, 5));
      }
    }
  }

  [Unity.Netcode.ServerRpc]
  private void MoveServerRpc(float x, float z)
  {
    this.moveInput = new Vector3(x, 0, z);
  }
  private void Move()
  {
    var delta = new Vector3(moveInput.x, 0, moveInput.z);

    transform.position += delta * speed * Time.deltaTime;
  }
}

動作確認

Animator の同期