네트워크 컬렉션
개요
Fusion은 네트워크 속성으로 사용할 수 있는 구조체 기반의 컬렉션 타입을 제공합니다.
- NetworkArray<T>
- NetworkDictionary<K, V>
- NetworkLinkedList<T>
- NetworkString<Size>
이 컬렉션들은 참조 타입이 아닌 구조체이므로, C# 컬렉션과 약간의 사용 차이가 있을 수 있습니다. (자세한 내용은 Usage In INetworkStructs 참조)
허용되는 T/K/V 타입은 다음과 같습니다:
- 기본 타입
byte
,sbyte
Int16
,Int32
,Int64
UInt16
,UInt32
,UInt64
float
double
- 유니티 구조체 타입 (ILWeaver.cs에서 정의)
Vector2
,Vector3
,Vector4
Quaternion
Matrix4x4
Vector2Int
,Vector3Int
BoundingSphere
Bounds
Rect
BoundsInt
RectInt
Color
,Color32
- System.Guid
- 사용자 정의 INetworkStruct
- Fusion 정의 INetworkStruct
- 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]
속성과 함께 속성(Property)으로 정의되어야 합니다. [Networked]
속성은 ILWeaver
가 이 컬렉션을 관련 NetworkRunner
및 Simulation
인스턴스의 메모리에 연결하는 코드를 생성하도록 지시합니다.
[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
는 Fusion에서 네트워크 속성으로 사용할 수 있는 C# Dictionary
의 구조체 대체입니다. NetworkDictionary
는 완전한 IDictionary
구현은 아니지만, 주요 멤버는 대부분 제공됩니다.
주요 메소드 및 속성:
- 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의 구조체 대체로, 용량의 일부만 사용할 수 있습니다. 추가된 항목은 백업 데이터의 비어 있는 슬롯에 추가됩니다. 항목이 제거되더라도 백업 배열 데이터에서 다른 요소의 메모리 위치는 이동하지 않습니다. 대신 컬렉션은 구조체의 일부로 요소 순서에 대한 데이터를 저장하며, 열거자(enumerator)와 인덱서는 요소가 백업 배열에 저장된 순서가 아니라 추가된 순서대로 요소를 반환합니다.
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
은 문자열 데이터를 위한 고정 크기 컬렉션입니다. 크기(Size)는 미리 정의된 IFixedStorage
타입 중 하나를 사용할 수 있으며, 예를 들어 _32
는 크기가 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
타입의 네트워크 속성의 값을 수정할 때는 다음 사항을 반드시 준수하십시오:
INetworkStruct
의 복사본을 작업하여 수정된 복사본을 네트워크 속성에 적용하거나,- 네트워크 속성을
ref
로 정의하십시오. 네트워크 속성이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