プロジェクトをNetcode for GameObjectsのリリース版にアップデートする

はじめに

エンジニアの松原です。先日Unityがマルチプレイヤーのための新しいツール群の発表をUnityの公式ブログから発表がありました。

この中に含まれるNetcode for GameObjectsに関してはこのテックブログでもいくつかの記事(その1その2その3その4その5)で触れていましたが、正式リリース前のものでした。
この機会に知識のアップデートを行いたいと思い、以前作ったプロジェクトで使われていたNetcode for GameObjectsのバージョンをリリース版(2022年10月時点の最新は1.0.2)にアップデートする作業を記事にしました。 今回の内容について個人のGitHubリポジトリにアップロードしておりますので、もしよろしければ触ってみてください!

github.com

リポジトリを触る際の注意事項

今回の記事ではPhoton Realtimeに触れている部分があるため、前回の記事を参考にしつつ、 Assets/Photon/Resources/PhotonSettings.asset をインスペクタから設定し、App Id Realtimeにご自身で用意したPhotonのApp Idを追加しておきます。これをしておかないとネットワークが正常に動作しないと思います。

古いUnityのバージョンのプロジェクトでは再度パッケージを追加し直す必要がある

以前の記事ではプレリリース版のNetcode for GameObjectsを利用していたのですが、その時のUnityのバージョンは2021.2.3f1を利用していました。 この記事で利用したUnityプロジェクトからリリース版( 1.0.0 or 1.0.1 or 1.0.2 )が利用できるかPackage Managerからアップデートを検索したのですが、1.0.0-pre.10 (更新日は2022/6/22)のものまでしか出てきませんでした。 試しに2021.2系の最終バージョンである2021.2.19を入れてみても、同様に 1.0.0-pre.10 までしか認識していないようでした。

Unity公式のNetcode for GameObjectsのリリースノートを見てみましたが、この理由に関しては特に記載が見つかりませんでした。

ダメ元で再度パッケージを追加するためパッケージマネージャーの左上の「+」マークを押して、「Add package from git URL...」を押し、リポジトリ名である com.unity.netcode.gameobjects を入力しパッケージを追加し直したところ、リリース版( 1.0.2 )を読み込んでくれました。
この辺りの挙動の理由は分かりませんが、他のパッケージの場合でも、最新アップデートが候補に出てこないときは再度パッケージ自体を追加し直す作業で改善する可能性はありそうです。

公式では2020.3以降がサポート対象となっていますが、別の理由がない限りはこの機会に2021.3以降を使うのが良さそうです。 この問題が発生した直後に、試しに(2022/10/5)の2021.3系の最新版である2021.3.f11にプロジェクトバージョンを引き上げると上記対応をせずにアップデートできました。(GitHubのリポジトリは念のため、2021.2.3f1のままにしています)

Multiplayer Community Contributions(Photon)のバージョンをアップデートする

バージョン 1.0.0 以降では破壊的変更が含まれているため、前回の記事で取り上げたMultiplayer Community Contributionsの一つであるPhoton Realtime Transportのバージョンアップデート( 2.0.0 -> 2.0.1 )が必要です。
パッケージマネージャーの左上の「+」マークを押して、「Add package from git URL...」を押し、リポジトリ名を入れます。

コミットIDで導入するバージョンを固定しているため、URLが長くなっています。

https://github.com/Unity-Technologies/multiplayer-community-contributions.git?path=/Transports/com.community.netcode.transport.photon-realtime#9a480a58638b4bfbcc9fc6da4a5c39c216966aaf

2.0.1 のバージョンのパッケージが追加されました。

ClientNetworkTransformを更新する

バージョン 1.0.1 以降ではClientNetworkTransformに対しても変更が入っています。Unity公式ではPackageManagerから追加するようにコメントが書かれています。

The ClientNetworkTransform lives inside the Multiplayer Samples Utilities package. You can add this package via the Package Manager window in the Unity Editor by selecting add from Git URL and adding the following URL: https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop.git?path=/Packages/com.unity.multiplayer.samples.coop#main

つまりは、パッケージマネージャーで追加できるようにしており、パッケージマネージャーの左上の「+」マークを押して、「Add package from git URL...」を押し、リポジトリ名として以下のものを入れることでClientNetworkTransformを追加できるようになっているようです。

https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop.git?path=/Packages/com.unity.multiplayer.samples.coop#main

今回のプロジェクトファイルではAssetフォルダ以下でClientNetworkTransformのコードを管理していたため、こちらを直接書き換えて対応します。
ファイルは Assets/Samples/Netcode for GameObjects/1.0.0-pre.3/ClientNetworkTransform/ScriptsからAssets/Samples/Netcode for GameObjects/1.0.1/ClientNetworkTransform/Scriptsに移動し、ClientNetworkTransform.csを以下のリンクのコードに置き換えています。

github.com

using Unity.Netcode.Components;
using UnityEngine;

namespace Unity.Multiplayer.Samples.Utilities.ClientAuthority
{
    /// <summary>
    /// Used for syncing a transform with client side changes. This includes host. Pure server as owner isn't supported by this. Please use NetworkTransform
    /// for transforms that'll always be owned by the server.
    /// </summary>
    [DisallowMultipleComponent]
    public class ClientNetworkTransform : NetworkTransform
    {
        /// <summary>
        /// Used to determine who can write to this transform. Owner client only.
        /// This imposes state to the server. This is putting trust on your clients. Make sure no security-sensitive features use this transform.
        /// </summary>
        protected override bool OnIsServerAuthoritative()
        {
            return false;
        }
    }
}

破壊的変更のあったコードに対して修正を行う

リリース版以降で破壊的変更のあったコードを修正していきます。基本的にローレベルで処理を書いていたところでエラーが発生しており、ヘルパークラスやラッパークラスなどの変更による破壊的変更でエラーは発生していなかったので、プレリリース版から大きく仕様が変わっていないようでした。
ほとんど変更が無かったようで、あっさりと対応が済みました。

NetworkVariableのコンストラクタの引数を変更する

以前の記事で追加したコードのうち、PlayerSyncBehaviour.csで利用している、NetworkVariableのコンストラクタ周りに変更があったようで、第一引数に値の初期値を入れ、第二引数にNetworkVariableReadPermissionのタイプを指定する仕様に変わったようです。

    private readonly NetworkVariable<Vector3> networkMovingDirection = new NetworkVariable<Vector3>(
        Vector3.zero, // <- ここが増えた
        NetworkVariableReadPermission.Everyone
    );
    
    private readonly NetworkVariable<Vector3> networkCurrentPosition = new NetworkVariable<Vector3>(
        Vector3.zero, // <- ここが増えた
        NetworkVariableReadPermission.Everyone
    );

最後に

今回記事内容は短めでしたが、プレリリース版から破壊的変更が少なかっため、以前の記事で取り上げた知識やコードはほとんどそのまま利用できそうです。

前身であるUTPやMLAPIを含めると、Netcode for GameObjectsも例に漏れず、正式リリースまでに長い年月がかかっています。無事Netcode for GameObjectsがリリース版を迎え、安定軌道に乗った印象があります。
Unityの取り組んでいるプロジェクトの中では、長い間previewやexperimentalがついたままで、まだ正式リリースを迎えていないものもありますが、 Netcode for GameObjectsを含め、Unity Multiplayerは今回のリリースを踏まえ、Unityがかなり力を入れて取り組んでいるプロジェクトだと思います。
今後もUnity Multiplayerに関連するトピックは取り上げていきたいと思います。