1

我对扩展 Unity 编辑器非常陌生,并将这个脚本拼凑在一起,突出显示层次结构中的选定对象。问题是,当我在编辑器中并且堆栈顶部(场景名称)出现在树上时,整个层次结构变得不可见!当我向下滚动以使场景名称消失时,它会自行修复。我附上了图片,让您更好地了解正在发生的事情。当我有一堆对象时,这个问题很小,但在新场景中将无法使用。

[InitializeOnLoad]
public class HierarchyHighlighter
{
    static HierarchyHighlighter()
    {
        EditorApplication.hierarchyWindowItemOnGUI += HierarchyWindowItem_CB;
    }
    private static void HierarchyWindowItem_CB(int selectionID, Rect selectionRect)
    {
        Object o = EditorUtility.InstanceIDToObject(selectionID);
        if ((o as GameObject).GetComponent<HierarchyHighlighterComponent>() != null)
        {
            HierarchyHighlighterComponent h = (o as GameObject).GetComponent<HierarchyHighlighterComponent>();
            if (h.highlight)
            {
                if (Event.current.type == EventType.Repaint)
                {
                    GUI.backgroundColor = h.color;
                    GUI.Box(selectionRect, "");
                    GUI.backgroundColor = Color.white;
                    EditorApplication.RepaintHierarchyWindow();
                }
            }
        }
    }
}

控制台显示:“对象引用未设置为对象的实例” HierarchyHighlighter.HierarchyWindowItem_CB(Int32 selectionID, Rect selectionRect) (at Assets/HierarchyHighlighter.cs:18)

图像: 正常运行

无法正常运作

谢谢您的帮助!

4

1 回答 1

0

您的代码正在引发空引用异常。我不知道哪一行是 18,因为它在文件中可能与您发布的内容不同,但我的猜测Object o = EditorUtility...是返回 null 或者它返回的对象不是 GameObject 所以(o as GameObject)返回 null 并在您抛出异常时调用 GetComponent。

您还可以进行三个明显的优化:

  • 只做(o as GameObject)一次演员表。您甚至根本不需要 o 作为对象,因此您可以在得到它后立即GameObject o = EditorUtility.InstanceIDToObject(selectionID) as GameObject;进行强制转换:(然后检查 o 以修复异常)。
  • GetComponent 调用也一样:只执行一次。...Component h = o.GetComponent..., 那么if (h != null && h.highlight).
  • if (Event.current.type == EventType.Repaint)移至函数的开头,否则您将所有这些性能浪费在所有其他 gui 事件上。

此外,使用描述性变量名称。obj 和 highlighter 会比 o 和 h 好得多。

于 2016-12-05T01:13:44.303 回答