- Home /
Command/ClientRpc with generic parameter
Hi, I have a problem using generics with behaviours in Unity (5.2.3f1). I implemented an abstract generic class which derives from NetworkBehaviour and has two members, a Command and a ClientRpc method. This is perfectly valid C# code, yet the Unity compiler fails with a NRE. Is this expected and if so, why?
My code:
public abstract class MyGenericBehaviour<T> : NetworkBehaviour {
[Command]
protected virtual void CmdCommand(T param) {
//...
}
[ClientRpc]
protected virtual void RpcCall(T param) {
//...
}
}
The Unity compiler gives the following error:
UNetWeaver error: Exception :System.NullReferenceException: Object reference not set to an instance of an object at Unity.UNetWeaver.NetworkBehaviourProcessor.ProcessMethods () [0x002c2] in C:\buildslave\unity\build\Extensions\Networking\Weaver\UNetBehaviourProcessor.cs:1225 at Unity.UNetWeaver.NetworkBehaviourProcessor.Process () [0x00022] in C:\buildslave\unity\build\Extensions\Networking\Weaver\UNetBehaviourProcessor.cs:48 at Unity.UNetWeaver.Weaver.ProcessNetworkBehaviourType (Mono.Cecil.TypeDefinition td) [0x0008b] in C:\buildslave\unity\build\Extensions\Networking\Weaver\UNetWeaver.cs:1000 at Unity.UNetWeaver.Weaver.CheckNetworkBehaviour (Mono.Cecil.TypeDefinition td) [0x0008d] in C:\buildslave\unity\build\Extensions\Networking\Weaver\UNetWeaver.cs:1477 at Unity.UNetWeaver.Weaver.Weave (System.String assName, IEnumerable`1 dependencies, IAssemblyResolver assemblyResolver, System.String unityEngineDLLPath, System.String unityUNetDLLPath, System.String outputDir) [0x00098] in C:\buildslave\unity\build\Extensions\Networking\Weaver\UNetWeaver.cs:1586 UnityEngine.Debug:LogError(Object) Unity.UNetWeaver.Log:Error(String) (at C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:20) Unity.UNetWeaver.Weaver:WeaveAssemblies(IEnumerable`1, IEnumerable`1, IAssemblyResolver, String, String, String) (at C:/buildslave/unity/build/Extensions/Networking/Weaver/UNetWeaver.cs:1683) Unity.UNetWeaver.Program:Process(String, String, String, String[], String[], IAssemblyResolver, Action`1, Action`1) (at C:/buildslave/unity/build/Extensions/Networking/Weaver/Program.cs:34) UnityEditor.Scripting.Serialization.Weaver:WeaveUnetFromEditor(String, String, String, String, Boolean)
When I remove the Command/ClientRpc attribute or the generic method parameter, the compiler works as expected. I also noticed that using other attributes such as Server and ServerCallback work as expected.
Update
I tried to work around this issue by using a closed constructed type like this:
public abstract class MyGenericBehaviour<T> : NetworkBehaviour {
protected abstract void CmdCommand(T param);
protected abstract void RpcCall(T param);
}
public abstract class MyGenericBehaviourOfFloat : MyGenericBehaviour<float> {
[Command]
protected override void CmdCommand(float param) {
//...
}
[ClientRpc]
protected override void RpcCall(float param) {
//...
}
}
public MyConcreteBehaviour : MyGenericBehaviourOfFloat {
//...
}
This compiles, but fails at runtime with the following Exception:
InvalidProgramException: Invalid IL code in Assets.Scripts.Utils.MyGenericBehaviourOfFloat :OnSerialize (UnityEngine.Networking.NetworkWriter,bool): IL_0003: call 0x060001b7
Assets.Scripts.MyConcreteBehaviour.OnSerialize (UnityEngine.Networking.NetworkWriter writer, Boolean forceAll) UnityEngine.Networking.NetworkIdentity.UNetSerializeAllVars (UnityEngine.Networking.NetworkWriter writer) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:421) UnityEngine.Networking.NetworkServer.SendSpawnMessage (UnityEngine.Networking.NetworkIdentity uv, UnityEngine.Networking.NetworkConnection conn) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1397) UnityEngine.Networking.NetworkServer.ShowForConnection (UnityEngine.Networking.NetworkIdentity uv, UnityEngine.Networking.NetworkConnection conn) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1226) UnityEngine.Networking.NetworkConnection.AddToVisList (UnityEngine.Networking.NetworkIdentity uv) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:502) UnityEngine.Networking.NetworkIdentity.AddObserver (UnityEngine.Networking.NetworkConnection conn) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:721) UnityEngine.Networking.NetworkIdentity.RebuildObservers (Boolean initialize) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:759) UnityEngine.Networking.NetworkServer.SpawnObject (UnityEngine.GameObject obj) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1354) UnityEngine.Networking.NetworkServer.Spawn (UnityEngine.GameObject obj) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1573) UnityEngine.Networking.NetworkServer.FinishPlayerForConnection (UnityEngine.Networking.NetworkConnection conn, UnityEngine.Networking.NetworkIdentity uv, UnityEngine.GameObject playerGameObject) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1080) UnityEngine.Networking.NetworkServer.InternalAddPlayerForConnection (UnityEngine.Networking.NetworkConnection conn, UnityEngine.GameObject playerGameObject, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1014) UnityEngine.Networking.NetworkServer.AddPlayerForConnection (UnityEngine.Networking.NetworkConnection conn, UnityEngine.GameObject player, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:971) UnityEngine.Networking.NetworkManager.OnServerAddPlayerInternal (UnityEngine.Networking.NetworkConnection conn, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:816) UnityEngine.Networking.NetworkManager.OnServerAddPlayer (UnityEngine.Networking.NetworkConnection conn, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:782) UnityEngine.Networking.NetworkManager.OnServerAddPlayerMessageInternal (UnityEngine.Networking.NetworkMessage netMsg) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:669) UnityEngine.Networking.NetworkConnection.HandleReader (UnityEngine.Networking.NetworkReader reader, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:421) UnityEngine.Networking.NetworkConnection.HandleBytes (System.Byte[] buffer, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:377) UnityEngine.Networking.NetworkConnection.TransportRecieve (System.Byte[] bytes, Int32 numBytes, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:527) UnityEngine.Networking.NetworkServer.InternalUpdate () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:723) UnityEngine.Networking.NetworkServer.Update () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:585) UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:915)
Your answer
Follow this Question
Related Questions
MonoBehaviour pseudo-singleton with C# generics 1 Answer
2 problems with serialization of a generic list of a custom class 3 Answers
(analytics beta) How to initialize Generic Dictionary from JS? 1 Answer
Can I right a generic method for components having same member variable? 1 Answer
Is the class derived/inherited from generic list serializable? 1 Answer