This document is about: FUSION 2
SWITCH TO

INetworkStruct

概要

INetworkStructは、FusionのネットワークプロパティRPCで使用できる構造体を定義します。

独自のINetworkStructは、以下の条件を満たす必要があります。

  • 構造体型であること
  • INetworkStructを実装していること
  • Blittableであること

他のINetworkStruct内のフィールドとして、INetworkStructを入れ子にすることもできます。

Blittable要件

Blittableであるとは、マネージド・アンマネージド両方のコンテキストで、絶対的なメモリフットプリントを持つということです。そのため、INetworkStructのフィールドに以下を含めることはできません

  • 参照型
  • stringまたはchar(かわりにNetworkStringを使用してください)
  • bool(かわりにNetworkBoolまたはintを使用してください)

備考: ほとんどのユースケースで、boolはコンパイルも動作も可能ですが、異なるプラットフォーム間の動作は保証されていません。そのため、NetworkBoolの使用を推奨します。

詳細は.NetのBlittable型をご覧ください。

有効なフィールドの型

フィールドは、構造体のメモリフットプリントとアライメントに直接影響するため、Blittableである必要があります。自動実装ではないプロパティやExpression-bodiedなプロパティは、メモリレイアウトに影響を与えないため、型に制限はありません。

安全なフィールドの型は以下の通りです。

  • Blittable primitives
    • byte, sbyte
    • short, int, long
    • ushort, uint, ulong
    • float, double
  • Blittable Unity Struct Types
    • Vector2, Vector3, Vector4
    • Quaternion
    • Matrix4x4
    • Vector2Int, Vector3Int
    • BoundingSphere
    • Bounds
    • Rect
    • BoundsInt
    • RectInt
    • Color, Color32
  • Enums
  • System Blittable types (such as System.Guid)
  • User Defined Blittable Structs
  • User Defined INetworkStructs
  • Fusion Defined INetworkStructs
    • NetworkString<>
    • NetworkBool
    • Ptr
    • Angle
    • BitSet64, BitSet128, BitSet192, BitSet256
    • PlayerRefSet
    • NetworkId
    • NetworkButtons
    • NetworkRNG
    • NetworkObjectGuid
    • NetworkPrefabRef
    • NetworkObjectHeader
    • NetworkPrefabId
    • PlayerRef
    • SceneRef
    • TickTimer
    • IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512)
  • Network Collections
  • Fixed-Sized Buffers (unsafe: such as fixed int MyArray[32])

使用方法

INetworkStructのネットワークプロパティ

構造体は値型であることに注意してください。ネットワークプロパティでは、便利のためにrefキーワードを使用できるため、構造体をコピーすることなくプロパティを直接更新することができます。

C#

using Fusion;
using UnityEngine;

public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct NetworkStructExample : INetworkStruct
  {
    public int IntField;
  }

  // For convenience, declared Networked INetworkStructs can use the ref keyword,
  // which allows direct modification of members without needing to work with copies.
  [Networked]
  public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();

  // You can also declare Networked structs normally,
  // but be aware the getter will return a copy and not a reference.
  [Networked]
  public NetworkStructExample NetworkedStruct { get; set; }

  public override void Spawned()
  {
    NetworkedStruct.IntField = 5;
    Debug.Log(NetworkedStruct.IntField); // prints default value (0) and not 5.

    NetworkedStructRef.IntField = 5;
    Debug.Log(NetworkedStructRef.IntField); // prints 5
  }
}

Blittableな値型

浮動小数点数ではないBlittableなプリミティブ型は、基本的なフィールドとして宣言できます。追加のコードや属性は不要です。浮動小数点数型や、Unityの浮動小数点数ベースの構造体(Vector3など)は、浮動小数点数型をご覧ください。

C#

using Fusion;
using UnityEngine;


public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct NetworkStructExample : INetworkStruct
  {
    // Non-float primitive structs and Enum types, can be used normally as a field.
    // Except bools, which are non-blittable and cannot be used as fields.
    public SnapAxis   EnumField;
    public int        IntField;
    public Color32    Color32Field;
    public Vector2Int VectorIntField;
  }

浮動小数点数型

浮動小数点数型(プリミティブ・float型をラップする一般的なUnityの型)は、フィールドで使用できます。ただし、フィールドで使用した場合、Fusion ILWeaverによる圧縮処理やコード生成は行われません。

浮動小数点数型を自動的に圧縮するには、デフォルト実装のプロパティに[Networked]属性を追加してください。これで、Fusion ILWeaverによる圧縮処理済みの実装にプロパティが置換されます。

C#

using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct NetworkStructExample : INetworkStruct
  {
  // Recognized float-based Networked Properties will implement Fusion's compression.
  // Such as Float, Double, Vector2, Vector3, Color, Matrix etc.
  // Note: an auto-implemented property is allowed here.
  [Networked]
  public Vector3 CompressedVector { get; set; }

  [Networked]
  public float   CompressedFloat { get; set; }

  // Float types declared as fields will be uncompressed and will replicate bit for bit.
  // Typically you want compression, so this handling should not be used in most cases.
  public Vector3 UncompressedVector;
  public float   UncompressedFloat;
}

ブール型

ブール型はBlittableではないため、bool型をフィールドで安全に使用することはできません。Fusionが提供しているNetworkBool型は、boolと互換性を持ち、boolのプロパティより実装が楽で、Blittableです。

C#

using Fusion;
using UnityEngine;

public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct NetworkStructExample : INetworkStruct
  {
    // The preferred way to network a boolean is to use the NetworkBool type.
    public NetworkBool NetworkBool;

    // [Networked] is required for the primitive bool in order to instruct
    // the ILWeaver to create the required backing int and implementation.
    // Note that we do NOT declare this as an auto-implemented property,
    // but instead with an empty getter/setter.
    [Networked]
    public bool PrimitiveBool { get => default; set { } }

 }

自動実装プロパティでなければ、bool型を使用できます。

文字列

文字や文字列はBlittableではないので、string型をフィールドで安全に使用することはできませんが、自動実装プロパティでなければ使用できます。

Fusionが提供しているNetworkString<_size>型は、stringと互換性を持ち、省メモリ・効率的で、stringのプロパティより実装が楽です。

C#

using Fusion;
using UnityEngine;

public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct NetworkStructExample : INetworkStruct
  {
    // The easiest and cleanest way to use a string in an INetworkStruct
    // is to use the Fusion NetworkString<> type as a field.
    // _16 here indicates that we are allocating a capacity of 16 characters.
    public NetworkString<_16> Name;

    // Optionally a regular string can be used as a Property (not a field)
    [Networked]       // Notifies the ILWeaver to extend this property
    [Capacity(16)]    // allocates memory for 16 characters
    [UnityMultiline]  // Optional attribute to force multi-line in inspector.
    public string StringProperty { get => default; set { } }
  }

  // For convenience, declared Networked INetworkStructs can use the ref keyword,
  // which allows direct modification of members without needing to deal with copies.
  [Networked]
  public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();

  public override void Spawned()
  {
    NetworkedStructRef.Name = "John Conner";
  }
}

ネットワークコレクション

ネットワークコレクションの詳細は、Network Collectionsをご覧ください。

C#

using Fusion;
using UnityEngine;

public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct  NetworkStructExample : INetworkStruct
  {
    // Network Collections must be NOT be declared as auto-implemented properties,
    // and with only a default getter (the IL Weaver will replace the getter).
    [Networked, Capacity(16)]
    public NetworkDictionary<int, NetworkString<_4>> DictOfStrings => default;
  }

  // For convenience, declared Networked INetworkStructs can use the ref keyword,
  // which allows direct modification of members without needing to work with copies.
  [Networked]
  public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();

  public override void Spawned()
  {
    NetworkedStructRef.DictOfStrings.Set(1, "One");
    NetworkedStructRef.DictOfStrings.Set(4, "Four");

    Debug.Log($"Values Set: " +
              $"1:{NetworkedStructRef.DictOfStrings.Get(1)} " +
              $"4:{NetworkedStructRef.DictOfStrings[4]}");
  }
}

FusionのオブジェクトとID型

INetworkStructでは、FusionのオブジェクトをIDで解決できない(どのNetworkRunnerに紐づいているかを知らない)ので、IDはIDとして格納されます。これを解決するにはNetworkRunnerインスタンスが必須になるため、NetworkBehaviourでオブジェクトの参照を取得する必要があります。

C#

using Fusion;
using UnityEngine;

public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct NetworkStructExample : INetworkStruct
  {
    // Fusion Object and Ref ID types are backed by integers,
    // so they are blittable and can be used as basic fields.
    public NetworkId          NetworkIdField;
    public NetworkBehaviourId NetworkBehaviourIdField;
    public PlayerRef          PlayerRefField;
  }

  [Networked]
  public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();


  public override void Spawned()
  {
    // Capture this NetworkBehaviour's Id.
    NetworkedStructRef.NetworkBehaviourIdField = this;
  }

  public override unsafe void FixedUpdateNetwork()
  {
    // Look up the NetworkObject on the Runner using the networked ID.
    Runner.TryFindBehaviour(NetworkedStructRef.NetworkBehaviourIdField, out var nb);
    Debug.LogWarning($"NBID: {(nb == null ? "Null NB" : nb.Id.ToString())}");
  }
}

INetworkStructの入れ子

INetworkStructを実装する構造体はBlittableなので、他のINetworkStruct内のフィールドに使用できます。

C#

using Fusion;
using UnityEngine;

public class NetworkStructSampleCode : NetworkBehaviour
{
  public struct InnerStruct : INetworkStruct
  {
    public int IntField;
  }

  public struct OuterStruct: INetworkStruct
  {
    public InnerStruct Inner;
  }

  [Networked]
  public ref OuterStruct Outer => ref MakeRef<OuterStruct>();
}

OnChanged(入れ子のINetworkStruct)

OnChangedコールバックは、入れ子のINetworkStruct構造体全体の変更を検知しますが、構造体内のどの値が変更されたかは識別できません。各フィールド/プロパティのコールバックが必要な場合は、NetworkBehaviour自身のネットワークプロパティとして変数を保持してください。

C#

using Fusion;
using UnityEngine;

public class NetworkStructSampleCode : NetworkBehaviour
{

  public struct NetworkStructExample : INetworkStruct
  {
    public NetworkBool NetworkBool;
  }

  [Networked(OnChanged = nameof(OnNetworkStructChanged))]
  public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();

  // Note that OnChanged monitors any changes to the ENTIRE INetworkStruct,
  // so this callback will be triggered by ANY changes to the struct.
  public static void OnNetworkStructChanged(Changed<NetworkStructSampleCode> changed)
  {
    Debug.LogWarning($"Bool changed {changed.Behaviour.NetworkedStructRef.NetworkBool}");
  }

  public override unsafe void FixedUpdateNetwork()
  {
    // Toggle the nested bool value every tick, to trigger the OnChanged callback.
    NetworkedStructRef.PrimitiveBool = !NetworkedStructRef.NetworkBool;
  }
}

固定サイズのバッファ(Unsafe)

メモリフットプリントとアライメントが厳密に定義されているため、Unsafeな固定サイズのバッファの使用は有効です。

C#

public struct NetworkStructExample : INetworkStruct
{
  // Fixed is allowed, and can be used for advanced custom unsafe handling.
  public unsafe fixed byte FixedArray[32];
}
Back to top