In Unity6 (6000.0.7f1), I’ve tried to redirect a method call to my own method using the MethodRedirect extension method from this GitHub repo.
From the Scenario1 example code in the GitHub repo, I produced the following code to test it:
using System;
using System.Reflection;
using UnityEditor;
namespace MethodRedirect
{
class Scenario1
{
[MenuItem("RedirectTo/Scenario1")]
static void Test()
{
UnityEngine.Debug.Log("Redirect : MethodRedirect.Scenario1.InternalInstanceMethod()");
UnityEngine.Debug.Log("To : MethodRedirect.Scenario1.PrivateInstanceMethod()");
Assembly assembly = Assembly.GetAssembly(typeof(Scenario1));
Type Scenario_Type = assembly.GetType("MethodRedirect.Scenario1");
MethodInfo Scenario_InternalInstanceMethod = Scenario_Type.GetMethod("InternalInstanceMethod", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo Scenario_PrivateInstanceMethod = Scenario_Type.GetMethod("PrivateInstanceMethod", BindingFlags.Instance | BindingFlags.NonPublic);
var token = Scenario_InternalInstanceMethod.RedirectTo(Scenario_PrivateInstanceMethod, true);
// Using "dynamic" type to resolve the following issue in x64 and Release (with code optimizations) builds.
//
// Symptom: the second call to method InternalInstanceMethod() does not return the expected string value
//
// Cause: the result from the first call to method InternalInstanceMethod() is cached and so the second
// call gets the cached value instead of making the call again.
//
// Remark: for some reason, without "dynamic" type, only the "Debug x86" build configuration would reevaluate
// the second call to InternalInstanceMethod() without using the cached string value.
//
// Also, using the [MethodImpl(MethodImplOptions.NoOptimization)] attribute on the method did not work.
dynamic scenario = (Scenario1)Activator.CreateInstance(Scenario_Type);
string methodName = scenario.InternalInstanceMethod();
UnityEngine.Debug.Log("Call MethodRedirect.Scenario1.InternalInstanceMethod => "+ methodName);
UnityEngine.Debug.Assert(methodName == "MethodRedirect.Scenario1.PrivateInstanceMethod");
if (methodName == "MethodRedirect.Scenario1.PrivateInstanceMethod")
{
UnityEngine.Debug.Log("nRestore...");
token.Restore();
UnityEngine.Debug.Log(token);
methodName = scenario.InternalInstanceMethod();
UnityEngine.Debug.Log("Call MethodRedirect.Scenario1.InternalInstanceMethod => "+ methodName.ToString());
UnityEngine.Debug.Assert(methodName == "MethodRedirect.Scenario1.InternalInstanceMethod");
if (methodName == "MethodRedirect.Scenario1.InternalInstanceMethod")
{
UnityEngine.Debug.Log("nSUCCESS!");
}
else
{
UnityEngine.Debug.Log("nRestore FAILED");
}
}
else
{
UnityEngine.Debug.Log("nRedirection FAILED");
}
Console.ReadKey();
}
internal string InternalInstanceMethod()
{
return "MethodRedirect.Scenario1.InternalInstanceMethod";
}
private string PrivateInstanceMethod()
{
return "MethodRedirect.Scenario1.PrivateInstanceMethod";
}
public string PublicInstanceMethod()
{
return "MethodRedirect.Scenario1.PublicInstanceMethod";
}
public static string PublicStaticMethod()
{
return "MethodRedirect.Scenario1.PublicStaticMethod";
}
}
}
Now when choosing the RedirectTo->Scenario1 Menu, the console shows the following:
Any ideas about what could cause this failure and how to get this running?