在日常的工作和研究中,当给我们的场景摆放过多的物件的时候,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);
    }
}

按字母降序排列

public class DescendingSort : 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( 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 {
    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 .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
{
    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);
    }
    public override GUIContent content {
        get { return new GUIContent( "升序"); }
    }
}

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

public class AscendingSort : BaseHierarchySort {
    private readonly GUIContent _content;
 
    public AscendingSort() {
        Texture2D image = Resources. Load<Texture2D >("Fire");
        if (image ) {
            _content = new GUIContent( "升序", image , "升序排列");
        }
        else {
            _content = new GUIContent( "升序", "升序排列" );
        }
    }
 
    public override GUIContent content {
        get { return _content; }
    }
    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);
    }
}

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

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