在运行时检测层次结构更改 [英] detect hierarchy change during runtime

查看:271
本文介绍了在运行时检测层次结构更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个附加到UI游戏对象的脚本,该脚本查找并获取对画布根游戏对象的引用.现在,如果游戏对象移到层次结构中的其他位置并且画布根已更改,我将继续每个update()刷新参考.

I have a script attached to an UI gameobject that find and get reference to the canvas root gameobject. Right now i keep refreshing the reference every update() in case the gameobject is moved to other place in hierarchy and the canvas root changed .

但是我发现我的脚本要保持每个update()连续运行GetComponentInParent<Canvas>().rootCanvas的性能非常沉重,尤其是当对象位于具有1000多个游戏对象的层次结构的底部时.因此,我希望脚本仅在start()和对象层次结构更改时找到根画布.

But i found it performance heavy for my script to keep running GetComponentInParent<Canvas>().rootCanvas every single update() especially when the object is at the bottom of a hierarchy with 1000+ gameobject. So i want my script to only find root canvas at start() and when the object hierarchy changed.

我找到了 https://docs.unity3d.com/ScriptReference/EditorApplication -hierarchyChanged.html ,但仅供编辑器使用,构建后将不遵循.有什么办法可以做类似于OnHierarchyChanged()的事情吗?还使用循环检查层次结构的当前状态不在选项之内.

I've found https://docs.unity3d.com/ScriptReference/EditorApplication-hierarchyChanged.html but it is editor-only and won't follow after build. Is there any way to do something similar to OnHierarchyChanged() ? Also using loop to check the current state of hierarchy is out of option .

推荐答案

一些想法:

  1. 第一个,GetComponentInParent<Canvas>很贵,但是 只需调用Transform.parent?您只需要实例化 一开始就使用父级参考,即使您选中该参考 Update,价格便宜.
  2. 第二个,如果您知道(并且您应该知道)哪些事件 这会改变您的层次结构,您可以创建自己的委托, 事件,采取任何行动对其进行跟踪.
  3. 最后,我不确定这一点,但您检查了吗? Transform.hasChanged ?我认为这最后一个不会起作用,因为 只影响旋转,位置等...但是我不能保证正确 现在.
  1. First one, GetComponentInParent<Canvas> is expensive, but what about simply call Transform.parent? You only need to instantiate parent reference at the begining, and even if you check it on Update, is less expensive.
  2. Second one, if you know (and you should know) which are the events that changes your hierarchy, you can create your own delegate, event, action whatever to track it.
  3. And finally, I'm not sure about this one, but have you checked Transform.hasChanged? I think this last one won't work, cause only affect rotation, position etc...but I can't assure it right now.

举例2(我认为其他2相当清楚):

To exemplify Idea 2 (I think the other 2 are pretty clear):

using UnityEngine;
using System.Collections;

public class ClassThatCanChangeHierarchy : MonoBehaviour
{
    private List<GameObject> objectsThatWantToKnow = new List<GameObject>();

    private void MethodThatChangeHierarchy()
    {
        //your code that affects hierarchy...
        foreach(GameObject go in objectsThatWantToKnow)
        {
            go.GetComponent<ClassThatWantsToKnowWhenHierarchyChanges>().OnHierarchyChange?.Invoke();
        }
    }
}

using UnityEngine;    
using System;

public class ClassThatWantsToKnowWhenHierarchyChanges : MonoBehaviour
{
    public Action OnHierarchyChange = null;

    private void Awake()
    {
        OnHierarchyChange = () => Debug.log("hierarchy has changed");
    }
}

这篇关于在运行时检测层次结构更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆