概要
Netcode for GameObjectsで位置, アニメーションの同期を行います。
この記事では実装手順のみを紹介します。
初学者向けに細かい操作も書いておきます。
TL;DR
NetworkManagerとPlayerを用意してStartHost, StartClientする。
PlayerにはNetworkObjectともろもろ同期用のNetworkBehaviourを継承したクラスを付ける。
後は感覚で行ける。
1. プロジェクトを用意する
2. パッケージをインストールする
Unity Registry -> Netcode for GameObjects
※以前はUnity Transportを手動で入れる必要があったが自動で入れてくれるようになった。
3. シーン上にNetworkManagerを配置する
CreateEmptyして...
名前をNetworkManagerにしておく
作ったオブジェクトにNetworkManagerコンポーネントを付ける
4. Playerオブジェクトを用意する
ユニティちゃんを使う。
ダウンロードしてきたものをインポート。
一回シーンにおいて、AnimatorControllerを交換
NetworkObject, NetworkAnimator, NetworkTransform, NetworkRigidbody,NewScriptからPlayerControllerを追加
RigidbodyのFreezePositionとFreezeRotationを設定
PlayerControllerに以下のコードを記載
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
public class PlayerController : NetworkBehaviour
{
[SerializeField] float speed = 1f;
Animator animator;
void Start()
{
animator = GetComponent<Animator>();
}
void Update()
{
if (IsOwner)
{
var h = Input.GetAxis("Horizontal");
var v = Input.GetAxis("Vertical");
// サーバー(ホスト)のメソッドを呼び出す
MoveServerRpc(h, v);
}
if (IsServer)
{
// ステージから落ちたら戻してあげる
if (transform.position.y < -10.0)
{
transform.position = new Vector3(Random.Range(-3, 3), 3, Random.Range(-3, 3));
}
}
}
[ServerRpc]
void MoveServerRpc(float vertical, float horizontal)
{
// ここはサーバー(ホスト)でだけ処理される
var moveInput = new Vector3(horizontal, 0, vertical);
if (moveInput.magnitude > 0f)
transform.LookAt(transform.position + moveInput);
transform.position += moveInput * Time.deltaTime * speed;
animator.SetFloat("Speed", moveInput.magnitude);
}
}
5. 床を用意
6. NetworkManagerの設定
7. ボタンを追加
先ほど作ったNetworkManagerオブジェクトにAddCompornent -> NewScriptからNetworkManagerControllerを追加
NetworkManagerControllerの中に以下のコードを入れる
using Unity.Netcode;
using UnityEngine;
public class NetworkManagerController : MonoBehaviour
{
void OnGUI()
{
GUILayout.BeginArea(new Rect(10, 10, 300, 300));
if (GUILayout.Button("Host")) NetworkManager.Singleton.StartHost();
if (GUILayout.Button("Client")) NetworkManager.Singleton.StartClient();
if (GUILayout.Button("Server")) NetworkManager.Singleton.StartServer();
GUILayout.EndArea();
}
}
8.ビルド
Add Open Scenesを押して、Build And Runする。
9.実行
Build And Runが完了したら勝手にゲームが起動する。
↑これとエディタで位置とアニメーション同期を確認する
片方でHost、もう片方でClientを押すと、シーン上にキャラクターが2体出てくる。
AWSDや矢印キーで動ける。
完成!
まとめ
今回は簡単な位置同期とアニメーション同期を試してみました。
簡単とはいえマルチプレイをこれだけの作業で実装できるのは嬉しいです。
ただ、このままだと同じPC上でしか動きません。
NetworkManagerからIPを直接設定することでローカルネットワーク内で通信出来たり、Relayを使うことでインターネットの海を飛び越えることが出来たりします。
是非いろいろ試してみてください。
参考
以下を参考にしています。
本当に分かりやすく丁寧に説明してくださっているので是非見てみてください!!!
- Unity Netcode for GameObjectsを使ったオンラインマルチプレイゲーム開発Tips
https://media.colorfulpalette.co.jp/n/n08799dd4ae7e - Netcode for GameObjectsを使ってみよう - Unityステーション
https://www.youtube.com/watch?v=GRUtGLL8iMQ&t=50s&ab_channel=UnityJapan - How to use Unity Relay, Multiplayer through FIREWALL! (Unity Gaming Services)
https://www.youtube.com/watch?v=msPNJ2cxWfw&t=1095s&ab_channel=CodeMonkey - COMPLETE Unity Multiplayer Tutorial (Netcode for Game Objects)
https://www.youtube.com/watch?v=3yuBOB3VrCk&ab_channel=CodeMonkey - Unityの「Netcode for GameObjects」のサンプルで学ぶ co-opゲームの作り方
https://www.youtube.com/watch?v=-XQkv5Ugeq4&t=2067s&ab_channel=UnityJapan