Network Collection - cheona-thousand-man/Unity-myBasics-Wiki GitHub Wiki
- Fusion์ ๋คํธ์ํฌ๋ ์์ฑ์ผ๋ก ์ฌ์ฉํ ์ ์๋ ๊ตฌ์กฐ์ฒด ๊ธฐ๋ฐ์ ์ปฌ๋ ์
ํ์
์ ๊ณต
- NetworkArray
- NetwrkDictionary<K, V>
- NetworkLinkedList
- NetworkString
์ด ์ปฌ๋ ์ ๋ค์ ์ฐธ์กฐ ํ์ ์ด ์๋ ๊ตฌ์กฐ์ฒด๋ผ๋ ์ ์ ์ ์ํด์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ ์ผ๋ถ C# ์ปฌ๋ ์ ๊ณผ์ ์ฌ์ฉ๋ฒ ์ฐจ์ด๊ฐ ์์ต๋๋ค (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
- ์ฌ์ฉ์ ์ ์ INetworkStructs
- Fusion ์ ์ INetworkStructs
- NetworkString
- 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์ Simulation ์ธ์คํด์ค์ ๋ฐฑ์ ๋ฉ๋ชจ๋ฆฌ์ ์ฐ๊ฒฐํ๋ ์์ฑ ์ฝ๋๋ฅผ ์์ฑํ๋๋ก ์ง์
- [Capacity] ์์ฑ์ ์ต๋ ์์ ์๋ฅผ ์ง์ ํ๋ ๋ฐ ์ฌ์ฉ
- ์ฌ์ฉ ์ฌ๋ถ์ ๊ด๊ณ์์ด ์ด๋งํผ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ ๋น๋๋ฏ๋ก ์์๋๋ ์ต๋ ์์ ์๋ฅผ ์ถฉ์กฑํ ์ ์๋ ๊ฐ์ฅ ์์ ์ซ์ ์ ํ
- ์์๋ ๊ฐ์ด ๋ณ๊ฒฝ๋์ง ์๋ ํ ๋คํธ์ํฌ ํธ๋ํฝ ์์ฑX
// ๊ธฐ๋ณธ ๋คํธ์ํฌ ์ปฌ๋ ์
์ ์ธ
[Networked, Capacity(4)]
NetworkArray<int> NetArray => default;
NetworkArray, NetworkDictionary, NetworkLinkedList๊ฐ NetworkBehaviour์ ๋คํธ์ํฌ๋ ์์ฑ์ผ๋ก ์ ์ธ๋ ๋ MakeInitializer()
๋ฅผ ์ฌ์ฉํ์ฌ ์ด๊ธฐ ๊ฐ ์ ์
[Networked]
[Capacity(4)] // ์ปฌ๋ ์
์ ๊ณ ์ ์ฉ๋ ์ค์
NetworkArray<int> NetArray { get; }
// ์ ํ์ ์ด๊ธฐํ
= MakeInitializer(new int[] { 0, 1, 2, 3 });
[Networked, Capacity(4)]
NetworkLinkedList<int> NetLList { get; }
// ์ ํ์ ์ด๊ธฐํ
= MakeInitializer(new int[] { 0, 1, 2, 3 });
[Networked, Capacity(2)]
NetworkDictionary<int, int> NetDict { get; }
// ์ ํ์ ์ด๊ธฐํ
= MakeInitializer(new Dictionary<int, int> { { 0, 0 }, { 1, 1 } });
- NetworkArray๋ Fusion์์ ๋คํธ์ํฌ๋ ์์ฑ์ผ๋ก ์ฌ์ฉํ ์ ์๋ C# ๋ฐฐ์ด์ ๊ตฌ์กฐ์ฒด ๋์ฒด๋ฌผ
- NetworkArray๋ ๊ฐ์ ๊ฐ์ ธ์ค๊ณ ์ค์ ํ๋ ๋ฉ์๋์ ๋ค๋ฅธ ์ปฌ๋ ์ ์ผ๋ก ๋ณต์ฌํ ์ ์๋ IEnumerable ์ปฌ๋ ์
์ฃผ์ ๋ฉ์๋
- Get(int index)
- Set(int, T)
public class CollectionTestsArray : NetworkBehaviour
{
[Networked]
[Capacity(4)] // ์ปฌ๋ ์
์ ๊ณ ์ ์ฉ๋ ์ค์
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");
// NetworkDictionary ์์ฑ์์๋ ์ ํจํ์ง ์์ผ๋ฏ๋ก Set()์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
// 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๋ Fusion์์ ๋คํธ์ํฌ๋ ์์ฑ์ผ๋ก ์ฌ์ฉํ ์ ์๋ C# ๋์ ๋๋ฆฌ์ ๊ตฌ์กฐ์ฒด ๋์ฒด๋ฌผ
์ฃผ์ ๋ฉ์๋ ๋ฐ ์์ฑ
- 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)] // ์ปฌ๋ ์
์ ๊ณ ์ ์ฉ๋ ์ค์
[UnitySerializeField] // ์ธ์คํํฐ์ ์ด private ์์ฑ์ ํ์ํฉ๋๋ค.
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");
// ์ธ๋ฑ์๋ก ๊ฐ์ ์ค์ ํ๋ ๊ฒ์ ์ ํจํ์ง ์์ต๋๋ค.
// ์ด๊ฒ์ด struct ๊ธฐ๋ฐ NetworkDictionary์ C# Dictionary ์ฌ์ฉ๋ฒ์ ์ฐจ์ด์ ์ค ํ๋์
๋๋ค.
// NetDict[0] = "Foo"; // ์ด๋ ์ ํจํ์ง ์์ต๋๋ค.
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๋ NetworkArray์ ๊ตฌ์กฐ์ฒด ๋์ฒด๋ฌผ
- ์ถ๊ฐ๋ ํญ๋ชฉ์ ๋ฐฑ์ ๋ฐ์ดํฐ์ ๋น ์ฌ๋กฏ์ ์ถ๊ฐ
- ํญ๋ชฉ์ด ์ ๊ฑฐ๋ ๋, ๋ฐฑ์ ๋ฐฐ์ด ๋ฐ์ดํฐ๋ ๋ค๋ฅธ ์์๋ฅผ ๋ฉ๋ชจ๋ฆฌ์์ ์ด๋X
- ๊ตฌ์กฐ์ฒด์ ์ผ๋ถ๋ก ์์ ์์์ ๋ํ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ
- ์ด๊ฑฐ์์ ์ธ๋ฑ์๋ ๋ฐฑ์ ๋ฐฐ์ด์์ ์์๊ฐ ์์นํ ์์๊ฐ ์๋ ์ถ๊ฐ๋ ์์๋๋ก ์์ ๋ฐํ
public class NetworkLinkedListExample : NetworkBehaviour
{
[Networked]
[Capacity(4)] // ์ปฌ๋ ์
์ ๊ณ ์ ์ฉ๋ ์ค์
[UnitySerializeField] // ์ธ์คํํฐ์ ์ด private ์์ฑ์ ํ์ํฉ๋๋ค.
private NetworkLinkedList<NetworkString<_32>> NetList { get; }
= MakeInitializer(new NetworkString<_32>[] { "Zero", "One", "Two", "Four"});
public override void Spawned()
{
// ๋ ๋ฒ์งธ ํญ๋ชฉ์ ์ ๊ฑฐํ์ฌ ํ๋์ ๋น ์ฉ๋์ ๋จ๊น๋๋ค.
NetList.Remove("One");
// ๊ฐ์ผ๋ก ํญ๋ชฉ ์ฐพ๊ธฐ
NetList.Set(NetList.IndexOf("Two"), "TWO");
// ์ ํญ๋ชฉ ์ถ๊ฐ. ๋ฉ๋ชจ๋ฆฌ์์๋ ์ด์ ์ด๋ฆฐ ๋ฉ๋ชจ๋ฆฌ ์์น๋ฅผ ์ฑ์๋๋ค.
NetList.Add("Five");
// ์ธ๋ฑ์ค ์์๋ ๊ทธ๋๋ก ์ ์ง๋๋ฏ๋ก,
// ๋ณ๊ฒฝ๋ ๋ฉ๋ชจ๋ฆฌ ์์น๋ง ๋ํฐ ์ํ๊ฐ ๋์ด ๋คํธ์ํฌ๋ก ์ ์ก๋ฉ๋๋ค.
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();
}
}
}
๋คํธ์ํฌ ์์ฑ์ธ INetworkStruct์ ๊ฐ์ ์์ ํ ๋๋ ๋ค์ ์ค ํ๋๋ฅผ ๋ฐ๋์ ์ํ
- INetworkStruct์ ๋ณต์ฌ๋ณธ์ผ๋ก ์์ ํ ํ ์์ ๋ ๋ณต์ฌ๋ณธ์ ๋คํธ์ํฌ ์์ฑ์ ์ ์ฉ
- ๋คํธ์ํฌ ์์ฑ์ ์ฐธ์กฐ๋ก ์ ์
- ๋คํธ์ํฌ ์์ฑ์ด ์ฐธ์กฐ๋ก ์ ์ธ๋ ๊ฒฝ์ฐ, ๋ณต์ฌ๋ณธ์ ๋ง๋ค ํ์ ์์ด ์ฐธ์กฐ๋ฅผ ์ง์ ์์ ๊ฐ๋ฅ
๋คํธ์ํฌ ์์ฑ ์ ํ์ธ INetworkStruct๋ ์ด๊ธฐํ ๊ฐ๋ฅ
public class NetworkDictionaryTest : NetworkBehaviour
{
[System.Serializable]
struct NetworkStruct : INetworkStruct
{
[Networked, Capacity(16)]
public NetworkDictionary<int, int> NestedDict => default;
// NetworkString์ ์ผ๋ฐ ๊ตฌ์กฐ์ฒด์ด๋ฏ๋ก Fusion ์์ฑ์ด ํ์ ์์ต๋๋ค.
public NetworkString<_16> NestedString;
// ํ์ํ ๊ฒฝ์ฐ ๊ธฐ๋ณธ ์ด๊ธฐํ๋ฅผ ์์ฑ์ผ๋ก ์ ์ํฉ๋๋ค.
public static NetworkStruct Defaults
{
get
{
var result = new NetworkStruct();
result.NestedDict.Add(0, 0);
result.NestedString = "Initialized";
return result;
}
}
}
// ๊ฐ ํ์
์ผ๋ก ์ ์์ ์ผ๋ก ์ ์ธ๋ ์์ฑ
[Networked]
[UnitySerializeField]
private NetworkStruct NestedStruct { get; set; } = NetworkStruct.Defaults;
public void ModifyValues()
{
// NestedStruct๋ ๊ฐ ํ์
์ด๋ฏ๋ก ์์ ์ ๋ณต์ฌ๋ณธ์์ ์ํํ๊ณ ,
// ์์ ๋ ๊ฒฐ๊ณผ๋ฅผ ์์ฑ์ ๋ค์ ์ ์ฉํด์ผ ํฉ๋๋ค.
var copy = NestedStruct;
copy.NestedDict.Add(copy.NestedDict.Count, default);
copy.NestedString = System.IO.Path.GetRandomFileName();
NestedStruct = copy;
}
}
public class NetworkDictionaryTest : NetworkBehaviour
{
[System.Serializable]
struct NetworkStruct : INetworkStruct
{
[Networked, Capacity(16)]
public NetworkDictionary<int, int> NestedDict => default;
// NetworkString์ ์ผ๋ฐ ๊ตฌ์กฐ์ฒด์ด๋ฏ๋ก Fusion ์์ฑ์ด ํ์ ์์ต๋๋ค.
public NetworkString<_16> NestedString;
public static NetworkStruct Defaults
{
get
{
var result = new NetworkStruct();
result.NestedDict.Add(0, 0);
result.NestedString = "Initialized";
return result;
}
}
}
// ์ฐธ์กฐ ํ์
์ผ๋ก ์ ์ธ๋ ์์ฑ, ๊ฐ์ ์ง์ ์์ ๊ฐ๋ฅ
[Networked]
[UnitySerializeField]
private ref NetworkStruct NestedStruct => ref MakeRef(NetworkStruct.Defaults);
public void ModifyValues()
{
// NestedStruct๋ ์์์ ์ฐธ์กฐ๋ก ์ ์ธ๋์์ผ๋ฏ๋ก,
// ๋ณต์ฌ๋ณธ ์์ด ์ฐธ์กฐ๋ฅผ ์ง์ ์์ ํ ์ ์์ต๋๋ค.
NestedStruct.NestedDict.Add(NestedStruct.NestedDict.Count, default);
NestedStruct.NestedString = System.IO.Path.GetRandomFileName();
}
}