수정중인 페이지 입니다.

네트워크 컬렉션

개요

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에 이러한 컬렉션을 연결된 NetworkRunnerSimultation 인스턴스의 백업 메모리에 연결하는 속성 코드를 생성하도록 지시합니다.

[Capacity] 속성은 요소의 최대 수를 지정하는 데도 사용해야 합니다. 메모리는 사용량에 관계없이 이 많은 요소에 할당되므로 예상하는 가장 많은 요소를 처리할 수 있는 최소수를 선택하십시오. 요소는 값을 변경하지 않는 한 네트워크 트래픽을 생성하지 않습니다.

// A basic Network Collection declaration
[Networked, Capacity(4)]
NetworkArray<int> NetArray => default;

메인 화면으로

초기화

NetworkArray NetworkDictionary, 및 NetworkLinkedListNetworkBehaviour에서 네트워크 속성으로 선언되면 MakeInitializer()를 사용하여 초깃값을 정의할 수 있습니다.

[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)
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
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를 대체하는 구조체입니다. 추가된 항목은 백업 데이터의 열린 슬롯에 추가됩니다. 항목을 제거하면 백업 어레이 데이터가 메모리의 다른 요소를 이동하지 않습니다. 대신 이 컬렉션은 요소 순서에 대한 데이터를 구조의 일부로 저장하며 열거자 및 인덱서는 요소가 백업 배열에 상주하는 순서가 아닌 추가된 순서대로 요소를 반환합니다.

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자의 문자열을 저장할 수 있습니다.

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 내의 네트워크 컬렉션은 네트워크 속성으로 사용합니다.

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의 다음 네트워크 컬렉션을 참조 네트워크 속성으로 사용합니다.

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();
  }
}


기술문서 TOP으로 돌아가기