INetworkSerializable を用いて疑似的に NetworkVariableString を作る【Netcode for GameObjects】

検証環境

  • Unity 2021.2.2f1
  • Netcode for GameObjects 1.0.0-pre.2

はじめに

xrdnk.hateblo.jp

こちらと関連しています.
Netcode for GameObjects では,NetworkVariable で変数同期を行う際,
string は利用できないため,Unity Collection の FixedString32Bytes を利用しないといけない事情があります.

readonly NetworkVariable<FixedString32Bytes> _playerNameNV = new NetworkVariable<FixedString32Bytes>(new FixedString32Bytes(""));

こう書くのは個人的気持ち悪さがあるのでせっかくなので INetworkSerializable を使って楽をします.

INetworkSerializable

new MLAPI 時代と機能自体は変わりません.
自作の型を NetworkVariable や RPC で同期可能にするインタフェースです.

xrdnk.hateblo.jp

NGO 版では少し NetworkSerialize の所に諸々制約がついています.

struct MyComplexStruct : INetworkSerializable
{
    public Vector3 Position;
    public Quaternion Rotation;

    // INetworkSerializable
    void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    {
        serializer.SerializeValue(ref Position);
        serializer.SerializeValue(ref Rotation);
    }
}

docs-multiplayer.unity3d.com

サンプルコード

public struct NetworkString : INetworkSerializable
{
    FixedString32Bytes _data;

    /// <summary>
    /// INetworkSerializable 実装
    /// </summary>
    public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
    {
        serializer.SerializeValue(ref _data);
    }

    public override string ToString() => _data.ToString();

    /// <summary>
    /// NetworkString → string 変換
    /// </summary>
    public static implicit operator string(NetworkString s) => s.ToString();

    /// <summary>
    /// string → NetworkString 変換
    /// </summary>
    public static implicit operator NetworkString(string s) => new () { _data = new FixedString32Bytes(s) };
}

これによって,こう書けるようになります.

readonly NetworkVariable<NetworkString> _playerNameNV = new (string.Empty);