INetworkStruct
개요
INetworkStruct
는 Fusion에서 네트워크 속성 및 RPC 메소드에 사용될 수 있는 구조체를 정의합니다.
사용자 정의 INetworkStruct
는 다음 조건을 충족해야 합니다:
- 구조체(
struct
) 형식이어야 합니다. INetworkStruct
인터페이스를 구현해야 합니다.- 블리터블(blittable)이어야 합니다.
이 구조체는 다른 INetworkStruct
내의 필드로 중첩될 수도 있습니다.
블리터블 요구 사항
INetworkStruct
는 블리터블이어야 하며, 이는 관리 및 비관리 컨텍스트에서 절대적인 메모리 크기를 가져야 함을 의미합니다. 따라서 필드 멤버는 다음과 같을 수 없습니다:
- 참조 타입
string
또는char
(대신NetworkString
사용)bool
(대신NetworkBool
또는 정수(int) 사용)
참고: bool
은 대부분의 경우 컴파일되고 작동할 수 있지만, 플랫폼 간 보장이 되지 않으므로 NetworkBool
사용을 권장합니다.
허용되는 필드 타입
필드 멤버는 구조체의 메모리 크기 및 정렬에 직접적인 영향을 미치므로 반드시 블리터블 타입이어야 합니다. 자동 구현되지 않은 속성 멤버 및 메소드 멤버는 메모리 레이아웃에 영향을 미치지 않으므로 이러한 제한을 받지 않습니다.
허용되는 안전한 필드 타입은 다음과 같습니다:
- 블리터블 기본 타입
byte
,sbyte
short
,int
,long
ushort
,uint
,ulong
float
,double
- 블리터블 Unity 구조체 타입
Vector2
,Vector3
,Vector4
Quaternion
Matrix4x4
Vector2Int
,Vector3Int
BoundingSphere
Bounds
Rect
BoundsInt
RectInt
Color
,Color32
- Enums
- System 블리터블 타입
- 예:
System.Guid
- 예:
- 사용자 정의 블리터블 구조체
- 사용자 정의 INetworkStruct
- Fusion 정의 INetworkStruct
NetworkString<>
,NetworkBool
,Ptr
,Angle
BitSet64
,BitSet128
,BitSet192
,BitSet256
PlayerRefSet
,NetworkId
,NetworkButtons
,NetworkRNG
NetworkObjectGuid
,NetworkPrefabRef
,NetworkObjectHeader
NetworkPrefabId
,PlayerRef
,SceneRef
,TickTimer
IFixedStorage
(_2, _4, _8, _16, _32, _64, _128, _256, _512)
- 네트워크 컬렉션
- NetworkArray<T> (최대 길이는
[Capacity]
속성으로 설정, 기본값: 1) - NetworkDictionary<K, V> (최대 개수는
[Capacity]
로 설정) - NetworkLinkedList<T> (최대 개수는
[Capacity]
속성으로 설정) - NetworkString<_size>
- NetworkArray<T> (최대 길이는
- 고정 크기 버퍼 (unsafe: 예:
fixed int MyArray[32]
)
사용법
INetworkStruct를 네트워크 속성으로 사용하기
구조체는 값 타입임을 유의하십시오. 네트워크 속성은 ref
키워드를 사용하여 복사본을 다룰 필요 없이 멤버를 직접 수정할 수 있도록 편리하게 사용할 수 있습니다.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
public int IntField;
}
// For convenience, declared Networked INetworkStructs can use the ref keyword,
// which allows direct modification of members without needing to work with copies.
[Networked]
public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();
// You can also declare Networked structs normally,
// but be aware the getter will return a copy and not a reference.
[Networked]
public NetworkStructExample NetworkedStruct { get; set; }
public override void Spawned()
{
NetworkedStruct.IntField = 5;
Debug.Log(NetworkedStruct.IntField); // prints default value (0) and not 5.
NetworkedStructRef.IntField = 5;
Debug.Log(NetworkedStructRef.IntField); // prints 5
}
}
단순 블리터블 값 타입
블리터블 기본 타입은 간단한 필드로 선언할 수 있으며, 추가 코딩이나 속성이 필요하지 않습니다. 부동 소수점 타입 또는 Unity의 부동 소수점 기반 구조체(Vector3 등)의 경우 Float Types 섹션을 참조하십시오.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
// Non-float primitive structs and Enum types, can be used normally as a field.
// Except bools, which are non-blittable and cannot be used as fields.
public SnapAxis EnumField;
public int IntField;
public Color32 Color32Field;
public Vector2Int VectorIntField;
}
Float Types
부동 소수점 타입(기본 타입 및 유니티의 부동 소수점 기반 타입)은 필드로 사용할 수 있습니다. 그러나 필드로 사용될 경우, Fusion의 ILWeaver는 압축 처리를 생성하지 않습니다.
이러한 부동 소수점 타입을 자동으로 압축하려면, 기본 구현을 가진 속성에 [Networked]
속성을 사용하십시오. Fusion의 ILWeaver는 해당 구현을 압축 처리로 대체합니다.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
// Recognized float-based Networked Properties will implement Fusion's compression.
// Such as Float, Double, Vector2, Vector3, Color, Matrix etc.
// Note: an auto-implemented property is allowed here.
[Networked]
public Vector3 CompressedVector { get; set; }
[Networked]
public float CompressedFloat { get; set; }
// Float types declared as fields will be uncompressed and will replicate bit for bit.
// Typically you want compression, so this handling should not be used in most cases.
public Vector3 UncompressedVector;
public float UncompressedFloat;
}
Bools
Bools는 블리터블이 아니므로 필드로 사용할 수 없습니다. Fusion은 NetworkBool
을 제공하며, 이는 bool
과 상호 교환 가능하고, 블리터블이며 구현 코드가 더 간단합니다.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
// The preferred way to network a boolean is to use the NetworkBool type.
public NetworkBool NetworkBool;
// [Networked] is required for the primitive bool in order to instruct
// the ILWeaver to create the required backing int and implementation.
// Note that we do NOT declare this as an auto-implemented property,
// but instead with an empty getter/setter.
[Networked]
public bool PrimitiveBool { get => default; set { } }
}
bool
타입은 자동 구현되지 않는 속성(Property)으로 사용할 수 있습니다.
Strings
String
과 Char
타입은 블리터블이 아니므로 필드로 안전하게 사용할 수 없습니다. 그러나 자동 구현되지 않은 속성(Property)으로는 사용할 수 있습니다.
Fusion은 NetworkString<_size>
타입을 제공하며, 이는 string
과 상호 교환 가능하며, 더 적은 메모리 할당, 더 나은 성능을 제공하며, string
속성보다 구현 코드가 간단합니다.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
// The easiest and cleanest way to use a string in an INetworkStruct
// is to use the Fusion NetworkString<> type as a field.
// _16 here indicates that we are allocating a capacity of 16 characters.
public NetworkString<_16> Name;
// Optionally a regular string can be used as a Property (not a field)
[Networked] // Notifies the ILWeaver to extend this property
[Capacity(16)] // allocates memory for 16 characters
[UnityMultiline] // Optional attribute to force multi-line in inspector.
public string StringProperty { get => default; set { } }
}
// For convenience, declared Networked INetworkStructs can use the ref keyword,
// which allows direct modification of members without needing to deal with copies.
[Networked]
public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();
public override void Spawned()
{
NetworkedStructRef.Name = "John Conner";
}
}
네트워크 컬렉션
네트워크 컬렉션 사용에 대한 자세한 내용은 Network Collections 페이지를 참조하십시오.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
// Network Collections must be NOT be declared as auto-implemented properties,
// and with only a default getter (the IL Weaver will replace the getter).
[Networked, Capacity(16)]
public NetworkDictionary<int, NetworkString<_4>> DictOfStrings => default;
}
// For convenience, declared Networked INetworkStructs can use the ref keyword,
// which allows direct modification of members without needing to work with copies.
[Networked]
public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();
public override void Spawned()
{
NetworkedStructRef.DictOfStrings.Set(1, "One");
NetworkedStructRef.DictOfStrings.Set(4, "Four");
Debug.Log($"Values Set: " +
$"1:{NetworkedStructRef.DictOfStrings.Get(1)} " +
$"4:{NetworkedStructRef.DictOfStrings[4]}");
}
}
Fusion 객체 및 ID 타입
INetworkStruct
는 Fusion 객체를 ID로 확인할 수 없지만(NetworkRunner와 관련이 없기 때문), 해당 ID를 저장할 수는 있습니다. 참조 검색은 NetworkBehaviour
에서 NetworkRunner
인스턴스를 사용하여 수행해야 합니다.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
// Fusion Object and Ref ID types are backed by integers,
// so they are blittable and can be used as basic fields.
public NetworkId NetworkIdField;
public NetworkBehaviourId NetworkBehaviourIdField;
public PlayerRef PlayerRefField;
}
[Networked]
public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();
public override void Spawned()
{
// Capture this NetworkBehaviour's Id.
NetworkedStructRef.NetworkBehaviourIdField = this;
}
public override unsafe void FixedUpdateNetwork()
{
// Look up the NetworkObject on the Runner using the networked ID.
Runner.TryFindBehaviour(NetworkedStructRef.NetworkBehaviourIdField, out var nb);
Debug.LogWarning($"NBID: {(nb == null ? "Null NB" : nb.Id.ToString())}");
}
}
INetworkStruct 중첩
INetworkStruct
를 구현한 구조체는 블리터블이므로 다른 INetworkStruct
정의 내에서 필드로 사용할 수 있습니다.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct InnerStruct : INetworkStruct
{
public int IntField;
}
public struct OuterStruct: INetworkStruct
{
public InnerStruct Inner;
}
[Networked]
public ref OuterStruct Outer => ref MakeRef<OuterStruct>();
}
OnChanged와 중첩된 INetworkStruct
중첩된 INetworkStruct
의 OnChanged
콜백은 전체 구조체에서 발생한 변경 사항을 감지하며, 개별 값의 변경 사항은 모니터링할 수 없습니다. 개별 필드/속성에 대한 콜백이 필요하다면 해당 변수를 NetworkBehaviour
내에서 독립적인 네트워크 속성으로 유지하십시오.
C#
using Fusion;
using UnityEngine;
public class NetworkStructSampleCode : NetworkBehaviour
{
public struct NetworkStructExample : INetworkStruct
{
public NetworkBool NetworkBool;
}
[Networked(OnChanged = nameof(OnNetworkStructChanged))]
public ref NetworkStructExample NetworkedStructRef => ref MakeRef<NetworkStructExample>();
// Note that OnChanged monitors any changes to the ENTIRE INetworkStruct,
// so this callback will be triggered by ANY changes to the struct.
public static void OnNetworkStructChanged(Changed<NetworkStructSampleCode> changed)
{
Debug.LogWarning($"Bool changed {changed.Behaviour.NetworkedStructRef.NetworkBool}");
}
public override unsafe void FixedUpdateNetwork()
{
// Toggle the nested bool value every tick, to trigger the OnChanged callback.
NetworkedStructRef.PrimitiveBool = !NetworkedStructRef.NetworkBool;
}
}
고정 크기 버퍼 (Unsafe)
고정 크기 버퍼는 엄격히 정의된 메모리 크기와 정렬을 가지므로 유효합니다.
C#
public struct NetworkStructExample : INetworkStruct
{
// Fixed is allowed, and can be used for advanced custom unsafe handling.
public unsafe fixed byte FixedArray[32];
}
Back to top