1、拓展菜单
需要使用MenuItem特性
拓展Hierarchy面板,Create按钮下的菜单项都在GameObject下
代码示例
using UnityEngine;
using UnityEditor;
public class Test8_Hierarchy : MonoBehaviour
{
[MenuItem("GameObject/MyCreate/cube", false, 10)]
public static void CreateCube()
{
GameObject.CreatePrimitive(PrimitiveType.Cube);
}
}
效果展示
2、拓展布局
需要使用到事件EditorApplication.hierarchyWindowItemOnGUI
代码示例
using UnityEngine;
using UnityEditor;
public class Test8_Hierarchy
{
[MenuItem("GameObject/MyCreate/cube", false, 10)]
public static void CreateCube()
{
GameObject.CreatePrimitive(PrimitiveType.Cube);
}
[InitializeOnLoadMethod]
static void InitializeOnLoadMethod()
{
EditorApplication.hierarchyWindowItemOnGUI += delegate (int instanceID,
Rect selectionRect)
{
if (Selection.activeObject &&
instanceID == Selection.activeObject.GetInstanceID())
{
Rect rect = new Rect(selectionRect)
{
x = selectionRect.x - 22,
width = selectionRect.height,
height = selectionRect.height,
};
GUI.DrawTexture(rect, AssetDatabase.LoadAssetAtPath<Texture>("Assets/next.png"));
rect.width = 40;
rect.x = selectionRect.x + selectionRect.width - rect.width;
if (GUI.Button(rect, "click"))
{
Debug.LogFormat("click:{0}", Selection.activeObject.name);
}
}
};
}
}
效果展示
3、重写菜单
通过事件EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
代码示例
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class Test8_OverrideHierarchy
{
[MenuItem("Window/Test/yangfufeng")]
static void Test()
{
}
[MenuItem("Window/Test/yaogaoshang")]
static void Teat1()
{
}
[MenuItem("Window/Test/Unity/money")]
static void Test2()
{
}
[InitializeOnLoadMethod]
static void StartInitializeOnLoadMethod()
{
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
}
static void OnHierarchyGUI(int instanceID, Rect selectionRect)
{
if (Event.current != null && selectionRect.Contains(Event.current.mousePosition) && Event.current.button == 1 &&
Event.current.type <= EventType.MouseUp)
{
GameObject selectionGameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if (selectionGameObject)
{
Vector2 mousePosition = Event.current.mousePosition;
EditorUtility.DisplayPopupMenu(new Rect(mousePosition.x, mousePosition.y, 0, 0), "Window/Test", null);
Event.current.Use();
}
}
}
}
效果展示
重写创建image按钮
[MenuItem("GameObject/UI/Image")]
static void CreatImage()
{
if (Selection.activeTransform)
{
if (Selection.activeTransform.GetComponentInParent<Canvas>())
{
Image image = new GameObject("image").AddComponent<Image>();
image.raycastTarget = false;
image.transform.SetParent(Selection.activeTransform, false);
Selection.activeTransform = image.transform;
}
}
}
4、使用案例
案例一
实现功能
父物体所有的子物体,是否含有组件,如果有则根据组件的状态在前面绘制出状态对应的图标,并且当选中某个子物体时,显示按钮,可以修改该组件中的属性值,控制物体的是否启用
代码示例
子物体状态记录类
using UnityEngine;
public enum M_State
{
未执行,
已执行
}
public class Test8_CurState : MonoBehaviour
{
public M_State state;
public bool IsStart;
public bool IsFinished;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
父物体绘制目标类,该类需要记录需要绘制的物体的组件集合
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Test8_HierarchyTarget : MonoBehaviour
{
public List<Transform> trans;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
绘制类,需要挂载在父物体上
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
public class Test8_HierarchyExample : MonoBehaviour
{
public Test8_HierarchyTarget target;
// Update is called once per frame
void Update()
{
}
private void OnEnable()
{
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
}
private void OnDisable()
{
EditorApplication.hierarchyWindowItemOnGUI -= OnHierarchyGUI;
}
public void OnHierarchyGUI(int instanceID, Rect selectionRect)
{
GameObject curObj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if (curObj)
{
if (target.trans.Contains(curObj.transform))
{
Test8_CurState test8_CurState = curObj.GetComponent<Test8_CurState>();
if (test8_CurState == null)
return;
Rect rect = new Rect(selectionRect)
{
x = selectionRect.x - 22,
width = selectionRect.height,
height = selectionRect.height,
};
if (test8_CurState.state == M_State.已执行)
{
GUI.DrawTexture(rect, AssetDatabase.LoadAssetAtPath<Texture>("Assets/next.png"));
}
else
{
GUI.DrawTexture(rect, AssetDatabase.LoadAssetAtPath<Texture>("Assets/cur.png"));
}
rect.x -= 18;
curObj.SetActive(GUI.Toggle(rect, curObj.activeSelf, ""));
if (Selection.activeObject &&
instanceID == Selection.activeObject.GetInstanceID())
{
rect = new Rect(selectionRect)
{
x = selectionRect.x - 22,
width = selectionRect.height,
height = selectionRect.height,
};
rect.width = 40;
rect.x = selectionRect.x + selectionRect.width - rect.width;
if (GUI.Button(rect, "finish"))
{
Debug.LogFormat("click:{0}", Selection.activeObject.name);
test8_CurState.state = M_State.已执行;
test8_CurState.IsFinished = true;
}
rect.x -= 42;
if (GUI.Button(rect, "start"))
{
Debug.LogFormat("click:{0}", Selection.activeObject.name);
test8_CurState.state = M_State.已执行;
test8_CurState.IsStart = true;
}
}
}
}
}
}
效果展示
案例二
实现功能
控制物体显示与隐藏ActiveSelf,并绘制不同颜色区别
代码示例
using UnityEditor;
using UnityEngine;
[InitializeOnLoad]
public class Test8_HierarchyGUIActiveSelf
{
static Test8_HierarchyGUIActiveSelf()
{
EditorApplication.hierarchyWindowItemOnGUI += OnHierarchyGUI;
}
static void OnHierarchyGUI(int instanceID, Rect selectionRect)
{
GameObject curObj = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
if(curObj)
{
Rect rect = new Rect(selectionRect)
{
x = 33,
width = selectionRect.height,
height = selectionRect.height,
};
if (curObj.activeSelf)
{
DrawBackground(selectionRect, new Color(1, 0.97f, 0, 0.1f));
}
else
{
DrawBackground(selectionRect, new Color(1, 0.026f, 0, 0.1f));
}
//控制curObj的activeSelf状态
curObj.SetActive(GUI.Toggle(rect, curObj.activeSelf, ""));
}
}
static void DrawBackground(Rect rect, Color color)
{
if (Event.current.type == EventType.Repaint)
{
Color baseColor = GUI.color;
GUI.color = color;
Rect backRect = new Rect(rect);
float width = rect.x;
backRect.x = 0;
backRect.width += rect.width + rect.x;
GUIStyle hoveredItemBackgroundStyle = new GUIStyle("WhiteBackground");
GUI.Label(backRect, GUIContent.none, hoveredItemBackgroundStyle);
GUI.color = baseColor;
}
}
}
效果展示