[Unity Editor]10行代码搞定Hierarchy排序

本文介绍如何通过简单代码实现 Unity 编辑器 Hierarchy 面板的物件按字母顺序或其他方式进行排序的方法,并展示了如何自定义排序选项的显示。

  在日常的工作和研究中,当给我们的场景摆放过多的物件的时候,Hierarchy面板就会变得杂乱不堪。比如这样:

    过多的层次结构充斥在里面,根层的物件毫无序列可言,整个层次面板显示非常的杂乱不堪,如果还有使用代码添加的物件,那就更加的惨不忍睹。里面的物件没有任何的规律可言(当然如果你们的美术有强迫症的话,也许会把物件分类,按规律排列的整齐,如果不是就惨了)。如果费时费力的排列好里面的结构,过一段时间就又会变乱。
    而如果要在杂乱的层次结构中找到我们想要的物体就需要费些体力和眼神了,就如同在垃圾堆里找宝石一样。

如果Hierarchy能按字母排序的话,那该多好!一个简单的字母排序,就会让整个结构看起来都是规规矩矩、整整齐齐。不论怎样也都会好过没有排序的。
比如下面这样:

别放弃,天无绝人之路,想让Hierarchy按字母排序,非常的简单,整个文件只有10行代码,其中using xxx占用了2行,符号占用2行,类名和函数名各1行,真正工作的代码只有4行。
代码结构就是下面这样

效果就是下面这个样子


哈哈,不逗你了,下面开始说正经事了!!!



这是按字母升序排列

public class AscendingSort : BaseHierarchySort {
    public override int Compare( GameObject lhs , GameObject rhs) {
        if (lhs == rhs) { return 0; }
        if (lhs == null) { return -1; }
        if (rhs == null) { return 1; }
        return EditorUtility .NaturalCompare( lhs.name , rhs.name);
    }
}

按字母降序排列

publicclassDescendingSort:BaseHierarchySort{
    publicoverrideintCompare(GameObjectlhs,GameObjectrhs){
        if(lhs==rhs){return0;}
        if(lhs==null){return1;}
        if(rhs==null){return-1;}
        returnEditorUtility.NaturalCompare(rhs.name,lhs.name);
    }
}

按InstanceID排序

public class InstanceIDSort : BaseHierarchySort {
    public override int Compare( GameObject lhs , GameObject rhs) {
        if (lhs == rhs) { return 0; }
        if (lhs == null) { return -1; }
        if (rhs == null) { return 1; }
        return lhs .GetInstanceID(). CompareTo(rhs .GetInstanceID());
    }
}


按HashCode排序

public class HashCodeSort:BaseHierarchySort{
    publicoverrideintCompare(GameObjectlhs,GameObjectrhs){
        if(lhs==rhs){return0;}
        if(lhs==null){return-1;}
        if(rhs==null){return1;}
        returnlhs.GetHashCode().CompareTo(rhs.GetHashCode());
    }
}

InstanceID排序与HashCode排序是一样的,没有看出其中的差异。

当然除了排序,我们还可以干点其他的,比如把排序下拉框改成中文的,一样很简单,如下
如果想要你的下拉选项变成中文的,没关系一样可以搞定(以升序排列为例),如下

public class 升序排列: BaseHierarchySort {
    public override int Compare( GameObject lhs , GameObject rhs) {
        if (lhs == rhs) { return 0; }
        if (lhs == null) { return -1; }
        if (rhs == null) { return 1; }
        return EditorUtility .NaturalCompare( lhs.name , rhs.name);
    }
}

别担心,Unity的类名是可以使用中文名的,你就大胆的使用吧。

如果你不满足于只是下拉选择框是中文的,还希望上面的图标也变成中文,没关系,一样可以搞定,只需复写一下content就可以了

public class 升序排列:BaseHierarchySort
{
    publicoverrideintCompare(GameObjectlhs,GameObjectrhs)
    {
        if(lhs==rhs){return0;}
        if(lhs==null){return-1;}
        if(rhs==null){return1;}
        returnEditorUtility.NaturalCompare(lhs.name,rhs.name);
    }
    publicoverrideGUIContentcontent{
        get{returnnewGUIContent("升序");}
    }
}

显示图片也是没有问题的哦,给个图文混合显示的吧

public class AscendingSort:BaseHierarchySort{
    privatereadonlyGUIContent_content;
 
    publicAscendingSort(){
        Texture2Dimage=Resources.Load<Texture2D>("Fire");
        if(image){
            _content=newGUIContent("升序",image,"升序排列");
        }
        else{
            _content=newGUIContent("升序","升序排列");
        }
    }
 
    publicoverrideGUIContentcontent{
        get{return_content;}
    }
    publicoverrideintCompare(GameObjectlhs,GameObjectrhs){
        if(lhs==rhs){return0;}
        if(lhs==null){return-1;}
        if(rhs==null){return1;}
        returnEditorUtility.NaturalCompare(lhs.name,rhs.name);
    }
}


当然上面的也可以换成自定义的图片,自定义文字,自定义图片+文字,也可以给与美术进行提示等等。全部只看你返回的是一个什么样的content了,这里就不做更多的介绍了

项目工程下载地址 https://github.com/sevenfires/HierarchySort.git

Unity 中实现自定义 Hierarchy 窗口的编辑功能,通常需要使用 Unity编辑器扩展 API 来操作 Hierarchy 界面的显示与交互。Unity 提供了 `Editor` 类和 `EditorApplication` 相关的 API 来实现对 Hierarchy 的自定义绘制和交互处理。 下面是一个基本的代码示例,展示如何在 Hierarchy 窗口中为特定 GameObject 添加自定义图标和悬停提示: ```csharp using UnityEngine; using UnityEditor; [InitializeOnLoad] public class CustomHierarchyIcon : Editor { private static Texture2D customIcon; static CustomHierarchyIcon() { EditorApplication.hierarchyWindowItemOnGUI += DrawCustomIcon; } private static void DrawCustomIcon(int instanceID, Rect selectionRect) { GameObject go = EditorUtility.InstanceIDToObject(instanceID) as GameObject; if (go != null && go.GetComponent<CustomComponent>() != null) { // 加载自定义图标 if (customIcon == null) customIcon = Resources.Load<Texture2D>("Icons/custom_icon"); Rect iconRect = new Rect(selectionRect.x + selectionRect.width - 20, selectionRect.y, 16, 16); GUI.DrawTexture(iconRect, customIcon); // 悬停提示 if (Event.current.type == EventType.Repaint) { HierarchyWindowHoverContent hoverContent = new HierarchyWindowHoverContent(); hoverContent.content = new GUIContent("This GameObject has a CustomComponent attached."); EditorWindow.mouseOverWindow.GetType().GetMethod("SetHoverContent", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) .Invoke(EditorWindow.mouseOverWindow, new object[] { hoverContent }); } } } } ``` ### 说明: - `EditorApplication.hierarchyWindowItemOnGUI` 用于在 Hierarchy 窗口的每一项上绘制自定义内容。 - `InitializeOnLoad` 属性确保该类在 Unity 编辑器启动时自动加载。 - `DrawCustomIcon` 方法中,通过 `instanceID` 获取对应的 GameObject,并检查其是否包含特定组件(如 `CustomComponent`)。 - 如果满足条件,则绘制自定义图标并设置悬停提示[^4]。 ### 图标资源: - 图标应放置在 `Assets/Resources/Icons/` 文件夹下,并命名为 `custom_icon`。 - 图标大小建议为 16x16 像素,以适配 Hierarchy 窗口的显示区域。 ### 自定义组件: - `CustomComponent` 是一个自定义脚本,附加到需要在 Hierarchy 中显示图标的 GameObject 上。 ### 扩展功能: - 可以进一步扩展此功能,例如添加点击事件、动态图标切换、多图标支持等。 - 通过 `EditorApplication.hierarchyWindowItemOnGUI`,还可以实现更复杂的交互逻辑,如拖拽操作、右键菜单等。 ### 注意事项: - 在使用 `HierarchyWindowHoverContent` 设置悬停提示时,需通过反射调用 `SetHoverContent` 方法,因为该方法是私有的。 - 确保图标资源路径正确,否则会导致 `NullReferenceException`。 通过上述代码,可以在 Unity 编辑器Hierarchy 窗口中实现自定义的图标显示和交互功能,提升开发效率和用户体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值