INetworkStruct
概要
INetworkStructは、FusionのネットワークプロパティとRPCで使用できる構造体を定義します。
独自のINetworkStructは、以下の条件を満たす必要があります。
- 構造体型であること
INetworkStructを実装していること- Blittableであること
他のINetworkStruct内のフィールドとして、INetworkStructを入れ子にすることもできます。
Blittable要件
Blittableであるとは、マネージド・アンマネージド両方のコンテキストで、絶対的なメモリフットプリントを持つということです。そのため、INetworkStructのフィールドに以下を含めることはできません。
- 参照型
stringまたはchar(かわりにNetworkStringを使用してください)bool(かわりにNetworkBoolまたはintを使用してください)
備考: ほとんどのユースケースで、boolはコンパイルも動作も可能ですが、異なるプラットフォーム間の動作は保証されていません。そのため、NetworkBoolの使用を推奨します。
詳細は.NetのBlittable型をご覧ください。
有効なフィールドの型
フィールドは、構造体のメモリフットプリントとアライメントに直接影響するため、Blittableである必要があります。自動実装ではないプロパティや式形式メンバーは、メモリレイアウトに影響を与えないため、型に制限はありません。以下の表は、INetworkStructに含められる安全なフィールドの型です。
| Blittable Primitives | ||||
|---|---|---|---|---|
| byte | sbyte | short (Int16) | int (Int32) | long (Int64) |
| ushort (UInt16) | uint (UInt32) | ulong (UInt64) | float (Single) | double |
| Blittable Unity Struct Types | ||||
| Vector2 | Vector3 | Vector4 | Quaternion | Matrix4x4 |
| Vector2Int | Vector3Int | BoundingSphere | Bounds | Rect |
| BoundsInt | RectInt | Color | Color32 | |
| System and User Defined Blittable Types | ||||
| Enums | System Types such as System.Guid | Structs | Other INetworkStructs | |
| Fusion Defined INetworkStructs | ||||
| NetworkString<IFixedStorage> | NetworkBool | Ptr | Angle | TickTimer |
| PlayerRef | PlayerRefSet | SceneRef | NetworkId | NetworkObjectGuid |
| NetworkObjectHeader | NetworkPrefabRef | NetworkPrefabId | NetworkRNG | NetworkButtons |
| BitSet64 | BitSet128 | BitSet192 | BitSet256 | |
| IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512) | ||||
| Network collections | ||||
NetworkArray<T> with a maximum Length set using the [Capacity] attribute (defaults to 1) |
NetworkDictionary<K, V> with a maximum Count set using the [Capacity] |
NetworkLinkedList<T> with a maximum Count set using the Capacity attribute |
NetworkString<_size> with a maximum Size set using the any of the predefined IFixedStorage types, which are named _X, where X is the size of storage struct _32 for example |
|
| Fixed-Size 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な構造体は、基本的なフィールドとして宣言できます。追加のコードや属性は不要です。
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
// Primitives, blittable 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 float FloatField;
public Color32 Color32Field;
public Vector2Int VectorIntField;
public Vector3 VectorField;
// for additional compression Fusion's compressed structs can be used
public FloatCompressed CompressedFloatField;
public Vector3Compressed CompresssedVectorField;
}
ブール型
ブール型は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