1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

前提

基本的には以下のサイトを参考にさせていただいています。

※kazuma_f様、大変有意義な記事をありがとうございます!

Unity 6やInput Systemで実装する際に若干異なる点があったため、それを踏まえた備忘録として記載します。補足としてご覧ください。

環境構成

  • Unity 6
  • Unity Netcode for GameObjects (NGO)
  • Input System

パッケージのインストール

kazuma_f様の記事と同様の手順でパッケージをインストールします。

NetworkManagerの作成

kazuma_f様の記事と同様の手順でNetworkManagerを作成します。

NetworkPlayerの作成

  1. NetworkPlayerPrefabを作成します
  2. Synchronize TransformをFalseに変更します(後述のNetworkTransformで制御するため)
  3. 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を使用する際の主な変更点:

  1. NetworkTransform: NetworkTransformClientは不要。Authority ModeOwnerに設定
  2. Input System: PlayerInputコンポーネントではなく、生成されたC#クラスを直接使用することで、クライアント側の入力問題を解決
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?