前提
基本的には以下のサイトを参考にさせていただいています。
※kazuma_f様、大変有意義な記事をありがとうございます!
Unity 6やInput Systemで実装する際に若干異なる点があったため、それを踏まえた備忘録として記載します。補足としてご覧ください。
環境構成
- Unity 6
- Unity Netcode for GameObjects (NGO)
- Input System
パッケージのインストール
kazuma_f様の記事と同様の手順でパッケージをインストールします。
NetworkManagerの作成
kazuma_f様の記事と同様の手順でNetworkManagerを作成します。
NetworkPlayerの作成
- NetworkPlayerPrefabを作成します
-
Synchronize Transformを
Falseに変更します(後述のNetworkTransformで制御するため) - NetworkManagerの
Default Player Prefabにアタッチします
ネットワーク接続用のボタンを追加する
kazuma_f様の記事と同様の手順でボタンを追加します。
マルチプレイヤーを確認する
kazuma_f様の記事と同様の手順で動作確認を行います。
位置を同期する
Unity 6では、NetworkTransformの設定方法が変更されています。
-
NetworkTransformClientコンポーネントの作成は不要になりました -
NetworkTransformコンポーネントのAuthority Modeを**Owner**に設定してください
Playerを移動するコードを作成する
Input Systemを使用する際の注意点
PlayerInputコンポーネントを使用すると、クライアント側で入力が正しく取得できない問題が発生しました。
解決方法: Input Action AssetからC#クラスを生成し、直接利用することで問題を解決できました。
以下はInputActionsという名前のInput Action Assetを作成した場合のコード例です:
using UnityEngine;
using Unity.Netcode;
using UnityEngine.InputSystem;
public class PlayerMovement : NetworkBehaviour
{
private const float Speed = 5f;
private const float RotationSpeed = 500f;
// 生成されたC#ラッパー
private InputActions _actions;
private InputAction _moveAction;
private Vector2 _move;
private void Awake()
{
_actions = new InputActions();
}
public override void OnNetworkSpawn()
{
if (IsOwner) EnableInput();
else DisableInput();
}
private void OnEnable()
{
if (IsOwner) EnableInput();
}
private void OnDisable()
{
DisableInput();
}
private void OnDestroy()
{
DisableInput();
_actions?.Dispose();
}
private void EnableInput()
{
// 作成したAction Map名に置き換えてください
var map = _actions.Player;
_moveAction = map.Move;
// 入力値変更の購読
_moveAction.performed += OnMovePerformed;
_moveAction.canceled += OnMoveCanceled;
_actions.Enable();
map.Enable();
}
private void DisableInput()
{
if (_moveAction != null)
{
_moveAction.performed -= OnMovePerformed;
_moveAction.canceled -= OnMoveCanceled;
_moveAction = null;
}
_actions?.Disable();
_move = Vector2.zero;
}
private void OnMovePerformed(InputAction.CallbackContext ctx)
{
_move = ctx.ReadValue<Vector2>();
}
private void OnMoveCanceled(InputAction.CallbackContext ctx)
{
_move = Vector2.zero;
}
private void Update()
{
// オーナーのみ移動処理を実行
if (!IsOwner) return;
Vector3 dir = new Vector3(_move.x, 0f, _move.y);
if (dir.sqrMagnitude > 1e-6f) dir.Normalize();
// キャラクターを移動
transform.Translate(dir * Speed * Time.deltaTime, Space.World);
// 移動方向を向く
if (dir != Vector3.zero)
{
var to = Quaternion.LookRotation(dir, Vector3.up);
transform.rotation = Quaternion.RotateTowards(
transform.rotation, to, RotationSpeed * Time.deltaTime);
}
}
}
動作確認
移動が正常に同期されることを確認できました!
まとめ
Unity 6でNetcode for GameObjectsを使用する際の主な変更点:
-
NetworkTransform:
NetworkTransformClientは不要。Authority ModeをOwnerに設定 -
Input System:
PlayerInputコンポーネントではなく、生成されたC#クラスを直接使用することで、クライアント側の入力問題を解決




