ネットワークコレクション
概要
Fusionはネットワークプロパティに使用できる構造体ベースのコレクションタイプを提供します。
- NetworkArray<T>
- NetworkDictionary<K, V>
- NetworkLinkedList<T>
- NetworkString<Size>
これらのコレクションは構造体であり、参照型ではありません。これらのコレクションとC#のコレクションの間には、C#の使用法に関する若干の違いがあります(INetworkStructsでの使用法を参照)。
許容されるT/K/V型は以下の通りです:
- プリミティブ
- byte, sbyte
- Int16, Int32, Int64
- UInt16, UInt32, UInt64
- float
- double
- float
- double
- Unity 構造体型 (ILWeaver.csで定義)
- Vector2, Vector3, Vector4
- Quaternion
- Matrix4x4
- Vector2Int, Vector3Int
- BoundingSphere
- Bounds
- Rect
- BoundsInt
- RectInt
- Color, Color32
- System.Guid
- ユーザー定義のINetworkStructs
- Fusion定義のINetworkStructs
- NetworkString<IFixedStorage>
- NetworkBool
- Ptr
- Angle
- BitSet64, BitSet128, BitSet192, BitSet256
- PlayerRefSet
- NetworkId
- NetworkButtons
- NetworkRNG
- NetworkObjectGuid
- NetworkPrefabRef
- NetworkObjectHeader
- NetworkPrefabId
- SceneRef
- TickTimer
- IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512)
宣言
NetworkArray
, NetworkDictionary
, NetworkLinkedList
は [Networked]
属性を持つプロパティとして定義する必要があります。[Networked]
属性は ILWeaver
に、これらのコレクションを関連する NetworkRunner
と Simultation
インスタンスのバッキングメモリに接続するためのプロパティコードを生成するように指示します。
[Capacity]
属性は要素の最大数を指定するために使用されます。使用量に関係なく、この数の要素に対してメモリが割り当てられます。予想される最大の要素数をカバーするのに十分な最小の数を選択します。要素が値を変えない限り、ネットワークトラフィックを発生させることはありません。
C#
// A basic Network Collection declaration
[Networked, Capacity(4)]
NetworkArray<int> NetArray => default;
初期化
NetworkArray
NetworkDictionary
と NetworkLinkedList
が NetworkBehaviour
の Networked Property として宣言されている場合、 MakeInitializer()
を使用して初期値を定義することができます。
C#
[Networked]
[Capacity(4)] // Sets the fixed capacity of the collection
NetworkArray<int> NetArray { get; }
// Optional initialization
= MakeInitializer(new int[] { 0, 1, 2, 3 });
[Networked, Capacity(4)]
NetworkLinkedList<int> NetLList { get; }
// Optional initialization
= MakeInitializer(new int[] { 0, 1, 2, 3 });
[Networked, Capacity(2)]
NetworkDictionary<int, int> NetDict { get; }
// Optional initialization
= MakeInitializer(new Dictionary<int, int> { { 0, 0 }, { 1, 1 } });
NetworkArray<T>
NetworkArray
は、C# の配列に代わる構造体で、Fusion の Networked Property として使用することができます。C#の配列と完全に同じではありませんが、NetworkArray
は IEnumerable
コレクションで、値の取得や設定、他のコレクションとのコピーのメソッドを備えています。
主なメソッドは以下の通りです:
- Get(int index)
- Set(int, T)
C#
public class CollectionTestsArray : NetworkBehaviour
{
[Networked]
[Capacity(4)] // Sets the fixed capacity of the collection
NetworkArray<NetworkString<_32>> NetArray { get; } =
MakeInitializer(new NetworkString<_32>[] { "#0", "#1", "#2", "#3" });
public override void FixedUpdateNetwork()
{
NetArray.Set(0, "Zero");
NetArray.Set(1, "One");
NetArray.Set(2, "Two");
// This is invalid with a NetworkDictionary property, use Set() instead.
// NetArray[3] = "Three";
NetArray.Set(0, NetArray[0].ToUpper());
NetArray.Set(1, NetArray.Get(1).ToLower());
NetArray.Set(2, default);
for (int i = 0; i < NetArray.Length; ++i)
{
Debug.Log($"{i}: '{NetArray[i]}''");
}
}
}
NetworkDictionary<K, V>
NetworkDictionary
は、C# の Dictionary
に代わる構造体で、Fusion の Networked Property として使用することができます。 完全な IDictionary
の実装ではありませんが、期待される主要なメンバはすべて利用可能であり、 Dictionary
と同様の機能を備えています。
主なメソッドとプロパティは以下の通りです:
- Clear()
- Add(K, V)
- Remove(k)
- ContainsKey(K)
- ContainsValue(V)
- Get(K)
- Set(K, V)
- this[K]
- Capacity
- Count
C#
public class NetworkDictionaryExample : NetworkBehaviour
{
[Networked]
[Capacity(4)] // Sets the fixed capacity of the collection
[UnitySerializeField] // Show this private property in the inspector.
private NetworkDictionary<int, NetworkString<_32>> NetDict => default;
public override void FixedUpdateNetwork()
{
NetDict.Clear();
NetDict.Add(0, "Zero");
NetDict.Add(2, "Two");
NetDict.Add(5, "Five");
// Setting values with the indexer are not valid, this is one of the cases
// where the struct based NetworkDictionary differs in usage from Dictionary.
// NetDict[0] = "Foo"; // this is not valid.
if (NetDict.ContainsKey(0))
{
NetDict.Set(0, NetDict[0].ToUpper());
}
if (NetDict.TryGet(5, out var value))
{
NetDict.Set(5, value.ToLower());
}
NetDict.Remove(2);
foreach(var kvp in NetDict)
{
Debug.Log($"{NetDict.Count}/{NetDict.Capacity} Key:{kvp.Key} Value:{kvp.Value}");
}
}
}
NetworkLinkedList<T>
NetworkLinkedList
は NetworkArray
に代わる構造体で、容量のサブセットを使用することができます。追加されたアイテムは、バッキングデータの空きスロットに追加されます。アイテムが削除されると、バックアレイデータはメモリ内の他の要素を移動させません。コレクションは、構造体の一部として要素の順序に関するデータを保存します。列挙器とインデクサは、バックアレイに存在する順序ではなく、追加された順序で要素を返します。
C#
public class NetworkLinkedListExample : NetworkBehaviour
{
[Networked]
[Capacity(4)] // Sets the fixed capacity of the collection
[UnitySerializeField] // Show this private property in the inspector.
private NetworkLinkedList<NetworkString<_32>> NetList { get; }
= MakeInitializer(new NetworkString<_32>[] { "Zero", "One", "Two", "Four"});
public override void Spawned()
{
// Remove the second entry, leaving one open capacity.
NetList.Remove("One");
// Find an entry by value
NetList.Set(NetList.IndexOf("Two"), "TWO");
// Add a new entry. In memory it backfills the now open memory position.
NetList.Add("Five");
// The indexed order however remains in sequence,
// so only the changed memory position is dirty and networked.
Debug.Log($"List {NetList.Count}/{NetList.Capacity}" +
$"0:'{NetList[0]}' 1:'{NetList[1]}' 2:'{NetList[2]} 3:'{NetList[3]}'");
}
}
NetworkString<Size>
NetworkString
は文字列データ用の固定サイズのコレクションです。サイズには、あらかじめ定義されている IFixedStorage
型のいずれかを指定できます。X はストレージのサイズを表し、例えば _32 は uint[32]
にバックされ、最大で 32 文字の文字列を格納することができます。
C#
public class NetworkStringExample : NetworkBehaviour
{
[Networked]
public NetworkString<_16> NetString { get; set; }
public override void FixedUpdateNetwork()
{
if (Runner.IsServer) {
NetString = System.IO.Path.GetRandomFileName();
}
}
}
INetworkStructs での使用
INetworkStruct
である Networked Property の値を変更する際、次のいずれかを必ず行ってください:
INetworkStruct
のコピーで作業し、変更したコピーを Networked Property に適用します。- または、Networked Property を ref として定義します。ネットワークプロパティが参照として宣言されている場合、参照は直接変更で きるので、値をコピーする必要はありません。
INetworkStruct
型のネットワークプロパティは、初期化することができます (例として、以下のコードを参照してください)。
これらのネットワーク・コレクションをネットワーク・プロパティとして INetworkStructs
で使用します。
C#
public class NetworkDictionaryTest : NetworkBehaviour
{
[System.Serializable]
struct NetworkStruct : INetworkStruct
{
[Networked, Capacity(16)]
public NetworkDictionary<int, int> NestedDict => default;
// NetworkString is a normal struct, so it doesn't require any Fusion attributes
public NetworkString<_16> NestedString;
// Define default initialization as a property if needed.
public static NetworkStruct Defaults
{
get
{
var result = new NetworkStruct();
result.NestedDict.Add(0, 0);
result.NestedString = "Initialized";
return result;
}
}
}
// Property declared normally as a value type
[Networked]
[UnitySerializeField]
private NetworkStruct NestedStruct { get; set; } = NetworkStruct.Defaults;
public void ModifyValues()
{
// NestedStruct is a value type, so modifications need to be performed on a copy,
// and the modified result must be applied back to the property.
var copy = NestedStruct;
copy.NestedDict.Add(copy.NestedDict.Count, default);
copy.NestedString = System.IO.Path.GetRandomFileName();
NestedStruct = copy;
}
}
これらのネットワーク化されたコレクションを INetworkStruct
で 参照 ネットワーク化されたプロパティとして使用します。
C#
public class NetworkDictionaryTest : NetworkBehaviour
{
[System.Serializable]
struct NetworkStruct : INetworkStruct
{
[Networked, Capacity(16)]
public NetworkDictionary<int, int> NestedDict => default;
// NetworkString is a normal struct, so it doesn't require any Fusion attributes
public NetworkString<_16> NestedString;
public static NetworkStruct Defaults
{
get
{
var result = new NetworkStruct();
result.NestedDict.Add(0, 0);
result.NestedString = "Initialized";
return result;
}
}
}
// Property declared as ref type, allowing direct modification of values
[Networked]
[UnitySerializeField]
private ref NetworkStruct NestedStruct => ref MakeRef(NetworkStruct.Defaults);
public void ModifyValues()
{
// NestedStruct was declared as a ref above, so modifications
// may be made directly to the reference, without need for copies.
NestedStruct.NestedDict.Add(NestedStruct.NestedDict.Count, default);
NestedStruct.NestedString = System.IO.Path.GetRandomFileName();
}
}
Back to top