Unity-Technologies / com.unity.netcode.gameobjects

Netcode for GameObjects is a high-level netcode SDK that provides networking capabilities to GameObject/MonoBehaviour workflows within Unity and sits on top of underlying transport layer.
MIT License
2.1k stars 430 forks source link

How to use the "built-in support for `NativeHashMap`" of NetworkVariable #2960

Open wintbiit opened 1 week ago

wintbiit commented 1 week ago

NGO v1.9.1 Unity 2022.3.22f1

as release blog says, NetworkVariable now includes built-in support for NativeHashMap by #2813 , but how to use it?

Here is my NetworkBehaviour code:

public class NetworkCacheProvider : NetworkBehaviour
{
    public NetworkVariable<NativeHashMap<int, NativeArray<byte>>> dataCache = new();
}

However when spawn this NetworkObject I received error:

ArgumentException: Serialization has not been generated for type Unity.Collections.NativeHashMap`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[Unity.Collections.NativeArray`1[[System.Byte, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]. This can be addressed by adding a [GenerateSerializationForGenericParameterAttribute] to your generic class that serializes this value (if you are using one), adding [GenerateSerializationForTypeAttribute(typeof(Unity.Collections.NativeHashMap`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[Unity.Collections.NativeArray`1[[System.Byte, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]])] to the class or method that is attempting to serialize it, or creating a field on a NetworkBehaviour of type NetworkVariable. If this error continues to appear after doing one of those things and this is a type you can change, then either implement INetworkSerializable or mark it as serializable by memcpy by adding INetworkSerializeByMemcpy to its interface list to enable automatic serialization generation. If not, assign serialization code to UserNetworkVariableSerialization.WriteValue, UserNetworkVariableSerialization.ReadValue, and UserNetworkVariableSerialization.DuplicateValue, or if it's serializable by memcpy (contains no pointers), wrap it in ForceNetworkSerializeByMemcpy`1.
Unity.Netcode.FallbackSerializer`1[T].ThrowArgumentError () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariableSerialization.cs:1173)
Unity.Netcode.FallbackSerializer`1[T].Duplicate (T& value, T& duplicatedValue) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariableSerialization.cs:1232)
Unity.Netcode.FallbackSerializer`1[T].Unity.Netcode.INetworkVariableSerializer<T>.Duplicate (T& value, T& duplicatedValue) <0x12de2b60290 + 0x00062> in <0d5b386684364728b7b180a19ff6291f>:0
Unity.Netcode.NetworkVariableSerialization`1[T].Duplicate (T& value, T& duplicatedValue) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariableSerialization.cs:1691)
Unity.Netcode.NetworkVariable`1[T].OnInitialize () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariable.cs:44)
Unity.Netcode.NetworkVariableBase.Initialize (Unity.Netcode.NetworkBehaviour networkBehaviour) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/NetworkVariable/NetworkVariableBase.cs:56)
Services.Networking.NetworkCacheProvider.__initializeVariables () <0x12de2b5fdc0 + 0x000d2> in <0560aa043dc4402da1c11d0b813fe38c>:0
Unity.Netcode.NetworkBehaviour.InitializeVariables () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkBehaviour.cs:776)
Unity.Netcode.NetworkBehaviour.InternalOnNetworkSpawn () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkBehaviour.cs:631)
Unity.Netcode.NetworkObject.InvokeBehaviourNetworkSpawn () (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkObject.cs:1371)
Unity.Netcode.NetworkSpawnManager.SpawnNetworkObjectLocallyCommon (Unity.Netcode.NetworkObject networkObject, System.UInt64 networkId, System.Boolean sceneObject, System.Boolean playerObject, System.UInt64 ownerClientId, System.Boolean destroyWithScene) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Spawning/NetworkSpawnManager.cs:726)
Unity.Netcode.NetworkSpawnManager.SpawnNetworkObjectLocally (Unity.Netcode.NetworkObject networkObject, System.UInt64 networkId, System.Boolean sceneObject, System.Boolean playerObject, System.UInt64 ownerClientId, System.Boolean destroyWithScene) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Spawning/NetworkSpawnManager.cs:629)
Unity.Netcode.NetworkObject.SpawnInternal (System.Boolean destroyWithScene, System.UInt64 ownerClientId, System.Boolean playerObject) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkObject.cs:773)
Unity.Netcode.NetworkObject.SpawnWithOwnership (System.UInt64 clientId, System.Boolean destroyWithScene) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Core/NetworkObject.cs:872)
Unity.Netcode.NetworkSpawnManager.InstantiateAndSpawnNoParameterChecks (Unity.Netcode.NetworkObject networkPrefab, System.UInt64 ownerClientId, System.Boolean destroyWithScene, System.Boolean isPlayerObject, System.Boolean forceOverride, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Spawning/NetworkSpawnManager.cs:412)
Unity.Netcode.NetworkSpawnManager.InstantiateAndSpawn (Unity.Netcode.NetworkObject networkPrefab, System.UInt64 ownerClientId, System.Boolean destroyWithScene, System.Boolean isPlayerObject, System.Boolean forceOverride, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) (at ./Library/PackageCache/com.unity.netcode.gameobjects@1.9.1/Runtime/Spawning/NetworkSpawnManager.cs:389)

Obviously cannot add a [GenerateSerializationForType(typeof(NetworkVariable<NativeHashMap<int, NativeArray<byte>>>))] to fix this. So what's proper way to use NetworkVariable with NativeHashMap and etc mentioned in release blog?

ShadauxCat commented 3 days ago

In order to avoid adding a dependency on the Collections package, the support for those collections is hidden behind a project define. You have to add UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT to your project defines (project settings > player > scripting define symbols).