如何在Unity Editor Script中将Persistent Listener添加到Button.onClick事件

Uma*_*r M 9 c# unity-game-engine

我想做一件简单的事情:

  1. 创建一个新的 GameObject
  2. Button组件添加到gameObject.
  3. 向按钮的onClick事件添加持久监听器.

我试图注册的方法是在其他一些脚本中.这是我正在尝试的一段代码:

MyScript myScriptInstance = FindObjectOfType<MyScript>(); 
var go = new GameObject();
var btn = go.AddComponent<Button>();

var targetinfo = UnityEvent.GetValidMethodInfo(myScriptInstance,
"OnButtonClick", new Type[]{typeof(GameObject)});

var action = (UnityAction) Delegate.CreateDelegate(typeof(UnityAction),go, targetinfo, false);
UnityEventTools.AddPersistentListener(btn.onClick, action);
Run Code Online (Sandbox Code Playgroud)

MyScript.cs看起来像这样:

public class MyScript : MonoBehaviour
{
    public void OnButtonClick(GameObject sender)
    {
        // do some stuff here.
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,按钮Onclick侦听器是空的,如下所示:

在此输入图像描述

如果我换行

var action = (UnityAction) Delegate.CreateDelegate(typeof(UnityAction),
go, targetinfo, false);
Run Code Online (Sandbox Code Playgroud)

var action = (UnityAction) Delegate.CreateDelegate(typeof(UnityAction),
go, targetinfo, true);
Run Code Online (Sandbox Code Playgroud)

我明白了:

ArgumentException:方法参数长度不匹配System.Delegate.CreateDelegate(System.Type类型,System.Object firstArgument,System.Reflection.MethodInfo方法,Boolean throwOnBindFailure)

我遵循了这些说明,但不知道这里出了什么问题.

真的很感激任何形式的帮助.

Pro*_*mer 7

在花了很多时间之后,我得出结论,这是一个错误。这是一个Mono错误。

这里是参考:

Ref 1Ref 2Ref 3Ref 4

Unity不会很快解决此问题。他们通常不会修复与Mono有关的内容,因为他们已经在努力升级到最新的Mono运行时。

幸运的是,还有其他两种解决方法:

1。使用AddObjectPersistentListenerUnityAction与通用的参数然后在通用传递给Delegate.CreateDelegate函数。

MyScript myScriptInstance = FindObjectOfType<MyScript>();
var go = new GameObject();
var btn = go.AddComponent<Button>();

var targetinfo = UnityEvent.GetValidMethodInfo(myScriptInstance,
"OnButtonClick", new Type[] { typeof(GameObject) });

UnityAction<GameObject> action = Delegate.CreateDelegate(typeof(UnityAction<GameObject>), myScriptInstance, targetinfo, false) as UnityAction<GameObject>;

UnityEventTools.AddObjectPersistentListener<GameObject>(btn.onClick, action, go);
Run Code Online (Sandbox Code Playgroud)

2。不要使用Delegate.CreateDelegate。只需使用AddObjectPersistentListener

MyScript myScriptInstance = FindObjectOfType<MyScript>();
var go = new GameObject();
var btn = go.AddComponent<Button>();

UnityAction<GameObject> action = new UnityAction<GameObject>(myScriptInstance.OnButtonClick);
UnityEventTools.AddObjectPersistentListener<GameObject>(btn.onClick, action, go);
Run Code Online (Sandbox Code Playgroud)

如果这两个都给您:

在此处输入图片说明

第二种解决方案不需要通过反射找到函数。您必须在运行时绑定功能。第一个使用反射。

您可能需要使用第一个解决方案,因为它与您正在做的事情非常相似,并且可以将函数名称提供为字符串变量。