네트워크 컬렉션
개요
Fusion은 네트워크 속성에 사용할 수 있는 구조체-기반 컬렉션 유형을 제공합니다.
- NetworkArray<T>
- NetworkDictionary<K, V>
- NetworkLinkedList<T>
- NetworkString<Size>
이러한 컬렉션은 구조체이며 참조 유형이 아닙니다. 따라서 일부 C#과 약간의 사용 차이가 있습니다(see INetworkStructs 사용 방법 참고).
허용된 T/K/V 타입:
- INetworkStructs
- NetworkString<> (which is an
INetworkStruct
) - Fusion Types
- NetworkObject
- NetworkBehaviour
- PlayerRef
- NetworkBool
- ILWeaver.cs에 정의되어 있는 Unmanaged Types (원시 자료형과 유니티 구조체 타입)
- byte
- sbyte
- Int16
- UInt16
- Int32
- UInt32
- Int64
- UInt64
- float
- double
- Vector2
- Vector3
- Vector4
- Quaternion
- Matrix4x4
- Vector2Int
- Vector3Int
- BoundingSphere
- Bounds
- Rect
- BoundsInt
- RectInt
- Color
- Color32
- Guid
선언
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
에서 네트워크 속성으로 선언되면 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
는 Fusion에서 네트워크 속성으로 사용할 수 있는 C# 배열의 구조체 대안입니다. NetworkArray
는 C# 배열과 완전히 동일하지는 않지만 값을 가져오고 설정하고 다른 컬렉션과 복사하는 방법을 사용하는 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에서 네트워크 속성으로 사용할 수 있습니다. 완전한 것은 아니지만 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로 명명되며 여기에서 X는 스토리지 구조체 _32의 크기이며, 끝에 uint[32]
가 붙고 최대 32자의 문자열을 저장할 수 있습니다.
C#
public class NetworkStringExample : NetworkBehaviour
{
public NetworkString<_16> NetString { get; set; }
public override void FixedUpdateNetwork()
{
if (Runner.IsServer) {
NetString = System.IO.Path.GetRandomFileName();
}
}
}
INetworkStructs에서 사용
INetworkStruct
인 네트워크 속성의 값을 수정할 때는 다음 중 하나를 수행하십시오.
INetworkStruct
복사본을 사용하여 변경된 복사본을 네트워크 속성에 적용합니다.- 또는 네트워크 속성을 참조로 정의합니다. 네트워크 속성이 참조로 선언되면 참조를 직접 수정할 수 있으므로 값을 복사할 필요가 없습니다.
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