上集回顾
上一讲讲到了图标绘制,没有实现功能,这么做是有原因的,跟据我的分析,主要原因工作量太大,假如一次性吃完一个饼,我撑死,所以一点一点的来,之前有尝试想过,由于越想执行难度越大,在想的阶段就导致我放弃了写作。
so~ 慢慢来,会比较快,只要坚持!借用一句俗话:慢,才是快。
先上目标:
目标如题
- 在层级中结合、展开对象。
- 在层级中控制显示与隐藏对象。
准备工作:
层级中收缩对象,这东西在Unity提供的API中,有一个 Object.hideFlags 与功能想似
public enum HideFlags
{
None = 0,
HideInHierarchy = 1,
HideInInspector = 2,
DontSaveInEditor = 4,
NotEditable = 8,
DontSaveInBuild = 16,
DontUnloadUnusedAsset = 32,
DontSave = 52,
HideAndDontSave = 61
}
从字面上看,这是设置一个对象的显示隐藏的标签,我们的需要是在这个对象下,把它所有的子对象给进行收起,不过无妨,也就是稍微绕一绕。HideInInspector 这个值正是想要的。
另外添加与删除标签最好别用等号赋值,或与运算代替
添加 obj.hideFlags |= flag;
删除 obj.hideFlags &= ~flag;
实践
仍然是 Editor 文件夹下的 KMHierarchy 类,里面添加方法
1.结合与展开对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
/// <summary> /// 子对象相关信息,超过99显示99+,无子对象不显示。 /// </summary> private static void DrawCombine(GameObject go,Rect selectRect) { int childCount = go.transform.childCount; if (childCount == 0) return; //绘制的大小与坐标 Rect childRect = selectRect.H_CR(2, 6).H_Size(24); // 显示的文本 string text = childCount > 99 ? "99+" : childCount.ToString(); //取子对象是否隐藏 //FIX:此处我只取了第一个对象为代表,此方法并不雅观,如果有很好的方法,请联系我 bool isHide = HasFlag(go.transform.GetChild(0), HideFlags.HideInHierarchy); if (isHide) childRect = selectRect.H_CR(2, 11).H_Size(22); if (GUI.Button(childRect, text, isHide ? EditorStyles.miniButton : EditorStyles.label)) { bool isAdd = !isHide; SetChildrenFlag(go, HideFlags.HideInHierarchy, isAdd); } } //设置此对象所有子对象的Flag private static void SetChildrenFlag(GameObject go,HideFlags flag,bool isAdd) { foreach (Transform t in go.transform) { if (isAdd) t.hideFlags |= flag; else t.hideFlags &= ~flag; } //Work on 以下代码是让Editor的层级实时进行一下,因为 Hierarchy not update bool old = go.activeSelf; go.SetActive(!old); go.SetActive(old); } private static bool HasFlag(Transform t , HideFlags flag) { return (t.hideFlags & flag) > 0; } |
2.对象的显示与隐藏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/// <summary> /// 游戏对象Active相关信息 /// </summary> private static void DrawActive(GameObject go,Rect SelectRect) { //此对象是否显示中 bool isActiveInHierarchy = go.activeInHierarchy; string texName = isActiveInHierarchy ? "eye" : "eye_dis"; Rect eyeRect = SelectRect.H_CR(); GUI.DrawTexture(eyeRect, GetTexture2D(texName)); if (GUI.Button(eyeRect, "", EditorStyles.label)) { SetActiveInHierarchy(go, !isActiveInHierarchy); } } /// <summary> /// 设置对象显示状态 /// </summary> private static void SetActiveInHierarchy(GameObject go , bool active) { if (go.activeSelf != active) go.SetActive(active); if (go.activeInHierarchy != active) SetActiveInHierarchy(go.transform.parent.gameObject, active); } |
当然最重要的一步在回调方法中调绘制的方法:
1 2 3 4 5 6 7 8 9 |
private static void HierarchyItemCB(int instanceID, Rect selectionRect) { var go = EditorUtility.InstanceIDToObject(instanceID) as GameObject; if (go == null) return; DrawActive(go,selectionRect); DrawCombine(go, selectionRect); } |
效果对比展示,你会发现层级被收缩了起来。
已知BUG
当点击 收缩/展开 的图标时,场景检测并不会改变,此时你即使Ctrl + S保存场景也是无用的,这应该为Unity的BUG,我的版本是5.3.1f1,其中我观看了两个插件 2dToolKit 和 Hierarchy2 两个插件存在的问题。
如果有好的方法请留言,或者联系作者~
可以改进的地方
图标都是用的白色的,我们可以加入颜色,当然这还得考虑到我们可以切换Unity的背影颜色。
但是说白了,这都不是事。
标签中 NotEditable 应该为不可编辑状态,这个东西也可以做成功能。
血源诅咒还差最后一个杯就白金了,玩去。