diff --git a/com.unity.netcode.gameobjects/Editor/CodeGen/NetworkBehaviourILPP.cs b/com.unity.netcode.gameobjects/Editor/CodeGen/NetworkBehaviourILPP.cs index 0b09d7e84a..9c9c45f586 100644 --- a/com.unity.netcode.gameobjects/Editor/CodeGen/NetworkBehaviourILPP.cs +++ b/com.unity.netcode.gameobjects/Editor/CodeGen/NetworkBehaviourILPP.cs @@ -592,6 +592,27 @@ private void ProcessNetworkBehaviour(TypeDefinition typeDefinition, string[] ass instructions.Reverse(); instructions.ForEach(instruction => processor.Body.Instructions.Insert(0, instruction)); } + + // override NetworkBehaviour.__getTypeName() method to return concrete type + { + var baseType = typeDefinition.BaseType.Resolve(); + var baseGetTypeNameMethod = baseType.Methods.First(p => p.Name.Equals(nameof(NetworkBehaviour.__getTypeName))); + + var newGetTypeNameMethod = new MethodDefinition( + nameof(NetworkBehaviour.__getTypeName), + (baseGetTypeNameMethod.Attributes & ~MethodAttributes.NewSlot) | MethodAttributes.ReuseSlot, + baseGetTypeNameMethod.ReturnType) + { + ImplAttributes = baseGetTypeNameMethod.ImplAttributes, + SemanticsAttributes = baseGetTypeNameMethod.SemanticsAttributes + }; + + var processor = newGetTypeNameMethod.Body.GetILProcessor(); + processor.Body.Instructions.Add(processor.Create(OpCodes.Ldstr, typeDefinition.Name)); + processor.Body.Instructions.Add(processor.Create(OpCodes.Ret)); + + typeDefinition.Methods.Add(newGetTypeNameMethod); + } } private CustomAttribute CheckAndGetRpcAttribute(MethodDefinition methodDefinition) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index 31d4b5421d..d5c3692195 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -35,13 +35,18 @@ private static void SetUpdateStage(ref T param) where T : IHasUpdateStage } } +#pragma warning disable IDE1006 // disable naming rule violation check + // NetworkBehaviourILPP will override this in derived classes to return the name of the concrete type + internal virtual string __getTypeName() => nameof(NetworkBehaviour); +#pragma warning restore IDE1006 // restore naming rule violation check + #pragma warning disable 414 // disable assigned but its value is never used #pragma warning disable IDE1006 // disable naming rule violation check [NonSerialized] // RuntimeAccessModifiersILPP will make this `protected` internal __RpcExecStage __rpc_exec_stage = __RpcExecStage.None; #pragma warning restore 414 // restore assigned but its value is never used -#pragma warning restore IDE1006 // restore naming rule violation +#pragma warning restore IDE1006 // restore naming rule violation check #pragma warning disable IDE1006 // disable naming rule violation check // RuntimeAccessModifiersILPP will make this `protected` diff --git a/com.unity.netcode.gameobjects/Tests/Editor/NetworkBehaviourTests.cs b/com.unity.netcode.gameobjects/Tests/Editor/NetworkBehaviourTests.cs index 60f10b23c4..e6d9607702 100644 --- a/com.unity.netcode.gameobjects/Tests/Editor/NetworkBehaviourTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Editor/NetworkBehaviourTests.cs @@ -46,6 +46,15 @@ public void AccessNetworkObjectTest() Object.DestroyImmediate(gameObject); } + [Test] + public void GetNetworkBehaviourNameTest() + { + var gameObject = new GameObject(nameof(GetNetworkBehaviourNameTest)); + var networkBehaviour = gameObject.AddComponent(); + + Assert.AreEqual(nameof(EmptyNetworkBehaviour), networkBehaviour.__getTypeName()); + } + public class EmptyNetworkBehaviour : NetworkBehaviour {