How to use the "built-in support for `NativeHashMap`" of NetworkVariable
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/[email protected]/Runtime/NetworkVariable/NetworkVariableSerialization.cs:1173)
Unity.Netcode.FallbackSerializer`1[T].Duplicate (T& value, T& duplicatedValue) (at ./Library/PackageCache/[email protected]/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/[email protected]/Runtime/NetworkVariable/NetworkVariableSerialization.cs:1691)
Unity.Netcode.NetworkVariable`1[T].OnInitialize () (at ./Library/PackageCache/[email protected]/Runtime/NetworkVariable/NetworkVariable.cs:44)
Unity.Netcode.NetworkVariableBase.Initialize (Unity.Netcode.NetworkBehaviour networkBehaviour) (at ./Library/PackageCache/[email protected]/Runtime/NetworkVariable/NetworkVariableBase.cs:56)
Services.Networking.NetworkCacheProvider.__initializeVariables () <0x12de2b5fdc0 + 0x000d2> in <0560aa043dc4402da1c11d0b813fe38c>:0
Unity.Netcode.NetworkBehaviour.InitializeVariables () (at ./Library/PackageCache/[email protected]/Runtime/Core/NetworkBehaviour.cs:776)
Unity.Netcode.NetworkBehaviour.InternalOnNetworkSpawn () (at ./Library/PackageCache/[email protected]/Runtime/Core/NetworkBehaviour.cs:631)
Unity.Netcode.NetworkObject.InvokeBehaviourNetworkSpawn () (at ./Library/PackageCache/[email protected]/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/[email protected]/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/[email protected]/Runtime/Spawning/NetworkSpawnManager.cs:629)
Unity.Netcode.NetworkObject.SpawnInternal (System.Boolean destroyWithScene, System.UInt64 ownerClientId, System.Boolean playerObject) (at ./Library/PackageCache/[email protected]/Runtime/Core/NetworkObject.cs:773)
Unity.Netcode.NetworkObject.SpawnWithOwnership (System.UInt64 clientId, System.Boolean destroyWithScene) (at ./Library/PackageCache/[email protected]/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/[email protected]/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/[email protected]/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?
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).
ah, I know my problem here. NGO package did not specify the Unity.Collections dependency version, meanwhile actually NGO only support Unity.Collections v1 until now. This means using Unity.Collections v2 with NGO won't get any UPM error, however you'll get compile errors like
Library\PackageCache\[email protected]\Runtime\NetworkVariable\CollectionSerializationUtility.cs(575,54): error CS1955: Non-invocable member 'NativeHashSet<T>.Count' cannot be used like a method.
This seems to be some compatibility issues, can NGO support Unity.Collections v2 ?
@wintbiit You must have UTP v2.3 installed. Yeah, I think this is a version compatibility issue with NGO v1.x currently. NGO v2.0.0 accounts for the changes in the v2 collections package. (going to get this imported and in the queue anyway for NGO v1.x)