使用Instantiate()克隆对象会丢失侦听器

时间:2016-07-12 10:47:22

标签: button unity3d listener clone

使用Instantiate()在运行时克隆按钮时,其中包含侦听器的onClick事件,侦听器不存在于克隆中。

可以通过使用带有按钮的Canvas并附加此脚本来测试行为:

void Start () {
    var button = transform.GetChild (0);
    button.GetComponent<Button> ().onClick.AddListener (new UnityAction(() => Debug.Log("Event triggered!")));
    var button2 = Instantiate (button);
    button2.SetParent (transform);
}

单击时,克隆的按钮不会向控制台打印任何内容。 有没有办法克隆GameObject,以便它保留事件监听器?

1 个答案:

答案 0 :(得分:2)

运行时侦听器不是持久性的,因此不是序列化的。因此,克隆按钮时不会传递它们。

您必须将该方法添加到脚本中并将脚本附加到预制件上,以便将其序列化,或者像第一个那样通过代码进行分配。

  • 实例化。在预制件或a上调用Instantiate()时 生活在场景中的游戏对象,或其他任何东西 问题(从UnityEngine.Object派生的所有东西都可以 序列化),我们序列化对象,然后创建一个新对象,和 然后我们将数据“反序列化”到新对象上。 (然后我们运行 在我们使用它的不同变体中再次使用相同的序列化代码 报告正在引用哪些其他UnityEngine.Object。我们 然后检查所有引用的UnityEngine.Object是否属于它们 实例化的数据()。如果引用指向 一些“外部”(如纹理)我们保留该引用作为它 是,如果它指向“内部”(像孩子一样) gameobject),我们修改对相应副本的引用。)

http://blogs.unity3d.com/2014/06/24/serialization-in-unity/

对于AddListener

  • 此函数添加“非持久”委托,这意味着它不会显示在检查器中,并且在编辑器中退出播放模式时将被遗忘。这些不同于“持久性”侦听器,您可以在检查器中的编辑时添加这些侦听器,并且在编辑和播放模式之间保持这种状态。

https://docs.unity3d.com/ScriptReference/Events.UnityEvent.AddListener.html

由于这些原因,我假设非持久化不是序列化的,然后不传递给克隆对象。