我试着做一件简单的事情:
GameObject
Button
组件添加到GameObject
中。Button
的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);
MyScript.cs看起来是这样的:
public class MyScript : MonoBehaviour
{
public void OnButtonClick(GameObject sender)
{
// do some stuff here.
}
}
运行此代码时,Onclick侦听器按钮为空,如下所示:
如果我改变了路线
var action = (UnityAction) Delegate.CreateDelegate(typeof(UnityAction),
go, targetinfo, false);
至
var action = (UnityAction) Delegate.CreateDelegate(typeof(UnityAction),
go, targetinfo, true);
我得到:
ArgumentException:方法参数长度不匹配System.Delegate.CreateDelegate (System.Type类型,System.Object firstArgument,System.Reflection.MethodInfo方法,布尔throwOnBindFailure)
我跟踪了这些指示,但不知道这里出了什么问题。
任何形式的帮助都是值得感激的。
发布于 2016-12-07 21:16:47
在花了这么多时间在这个问题上,我得出结论,这是一个错误。这是一个Mono虫。
以下是参考资料:
团结不会很快解决这个问题。他们通常不会修复与Mono相关的东西,因为他们已经在努力升级到最新的Mono运行时。
幸运的是,还有两种解决办法:
AddObjectPersistentListener
和UnityAction
,然后将泛型传递给Delegate.CreateDelegate
函数。
UnityEvent.GetValidMethodInfo(myScriptInstance,myScriptInstance = FindObjectOfType();var go =新GameObject();var btn = go.AddComponent();var myScriptInstance= MyScript "OnButtonClick",new Type[] { typeof(GameObject) };UnityAction action = Delegate.CreateDelegate(typeof(UnityAction),myScriptInstance,targetinfo,false)为UnityAction;Delegate.CreateDelegate
.只需使用AddObjectPersistentListener
。
UnityEventTools.AddObjectPersistentListener(btn.onClick,MyScript myScriptInstance = FindObjectOfType();var go =新GameObject();var btn = go.AddComponent();UnityAction action =新UnityAction(myScriptInstance.OnButtonClick);这两种情况都给出了如下结论:
第二种解决方案不需要通过反射找到函数。必须在运行时之前绑定函数.第一种是使用反射。
您可能需要使用第一个解决方案,因为它非常类似您正在做的事情,并且可以将函数名作为字符串变量提供。
发布于 2016-12-07 21:34:15
也许我没有理解您的问题,但是Button脚本公开了onClick事件,您可以在代码中使用添加侦听器到。
下面是我使用的代码:
// Use this for initialization
void Start () {
MyScript myScriptInstance = FindObjectOfType<MyScript> ();
GameObject go = DefaultControls.CreateButton (new DefaultControls.Resources());
var btn = go.GetComponent<Button> ();
btn.onClick.AddListener (myScriptInstance.TestMethod);
}
下面是MyScript.TestMethod的代码:
public void TestMethod ()
{
Debug.Log ("TestMethod");
}
有几件事要注意:
发布于 2020-10-16 21:21:44
因为我还不能评论,谢谢你这么多@程序员的回答!我从第二个示例中编辑了您的代码,以便在编辑器中填充UnityEvents。在两个独立的脚本中复制和粘贴代码,一个是命名菜单,另一个是MyScript。确保菜单脚本位于一个名为Editor的文件夹中。
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor.Events;
using UnityEngine.Events;
public class Menu : Editor
{
[MenuItem("Test/CreateButton")]
public static void CreateButton()
{
GameObject temp = new GameObject();
temp.AddComponent<MyScript>();
MyScript myScriptInstance = temp.GetComponent<MyScript>();
var btn = temp.AddComponent<Button>();
UnityAction<GameObject> action = new UnityAction<GameObject>(myScriptInstance.OnButtonClick);
UnityEventTools.AddObjectPersistentListener<GameObject>(btn.onClick, action, temp);
UnityAction<GameObject> action1 = new UnityAction<GameObject>(myScriptInstance.TestClicker);
UnityEventTools.AddObjectPersistentListener<GameObject>(btn.onClick, action1, temp);
UnityAction<GameObject> action2 = new UnityAction<GameObject>(myScriptInstance.TestClicker);
UnityEventTools.AddObjectPersistentListener<GameObject>(myScriptInstance.test_Event, action2, temp);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class MyScript : MonoBehaviour
{
public UnityEvent test_Event = new UnityEvent();
public void OnButtonClick(GameObject sender)
{
Debug.Log("Button Clicked");
}
public void TestClicker(GameObject sender)
{
Debug.Log("Event is working");
}
}
https://stackoverflow.com/questions/40655089
复制相似问题