扩展编辑器以突出显示层次结构的问题
Issue with Extending Editor to Highlight the Hierarchy
我对扩展 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();
}
}
}
}
}
控制台显示:
"Object reference not set to an instance of an object"
HierarchyHighlighter.HierarchyWindowItem_CB(Int32 selectionID, Rect selectionRect) (at Assets/HierarchyHighlighter.cs:18)
图片:
Functioning as normal
Not functioning as normal
感谢您的帮助!
您的代码抛出空引用异常。我不知道哪一行是 18,因为它在文件中可能与您发布的不同,但我的猜测是 Object o = EditorUtility...
返回 null 或者它 returns 的对象不是 GameObject所以 (o as GameObject)
returns 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 好很多。
我对扩展 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();
}
}
}
}
}
控制台显示: "Object reference not set to an instance of an object" HierarchyHighlighter.HierarchyWindowItem_CB(Int32 selectionID, Rect selectionRect) (at Assets/HierarchyHighlighter.cs:18)
图片: Functioning as normal
Not functioning as normal
感谢您的帮助!
您的代码抛出空引用异常。我不知道哪一行是 18,因为它在文件中可能与您发布的不同,但我的猜测是 Object o = EditorUtility...
返回 null 或者它 returns 的对象不是 GameObject所以 (o as GameObject)
returns 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 好很多。