拓展编辑器 3 - HierarchyWindow

关键概念

  • [MenuItem(“GameObject/XXX”)] : 创建左上角的 Create 菜单项。如果跟已有的路径相同,将覆盖已有功能。
  • EditorApplication.hierarchyWindowItemOnGUI : 委托,处理 hierarchy 窗口对象的绘制。签名:void OnGUI(int instanceID, Rect selectionRect)。
    • int instanceID : 选中的 GameObject 的实例 ID 。
    • Rect seletctionRect : GameObject 在 Hierarchy 窗口的绘制区域。
  • Selection.activeObject : 当前选中的 Object , 包括资源对象,所以可能不是 GameObject
  • GameObject.GetInstanceID() : 获取对象的实例 ID。
  • AssetDatabase.LoadAssetAtPath(string path) : 从指定路径加载资源
  • Event : 编辑器事件。
    • Event.current : 当前事件
    • Event.current.mousePosition : 事件的鼠标位置
    • Event.current.button : 鼠标按键。 0:左键 1:右键 2:中键
    • Event.current.type : 事件类型。如:EventType.MouseDown/MouseUp
  • int EditorUtility.InstanceIDToObject(int instanceID) : 根据给定的实例 ID 找到Object。
  • EditorUtility.DisplayPopupMenu(Rect rect, string menuPath, MenuCommand command) : 显示一个弹出式窗口。

例子

using UnityEngine;
using UnityEditor;
using UnityEngine.UI;

public class HierarchyExtend
{
    [MenuItem("GameObject/My Create/Create Sphere", false, 0)]
    static void CreateSphere()
    {
        GameObject.CreatePrimitive(PrimitiveType.Sphere);
    }

    [InitializeOnLoadMethod]
    static void InitializeOnLoadMethod()
    {
        // 为了保证我们的逻辑先执行,所以不能用+=,+=会把我们的逻辑添加到最后
        EditorApplication.hierarchyWindowItemOnGUI = OnGUI + EditorApplication.hierarchyWindowItemOnGUI;
    }

    /// <summary>
    /// GUI 绘制
    /// </summary>
    /// <param name="instanceID"></param>
    /// <param name="selectionRect"></param>
    static void OnGUI(int instanceID, Rect selectionRect)
    {
        // 处理选中的GameObject
        if (Selection.activeGameObject && instanceID == Selection.activeGameObject.GetInstanceID())
        {
            float width = 50;
            float height = 20;
            selectionRect.x += selectionRect.width - width;
            selectionRect.height = height;
            if (GUI.Button(selectionRect, AssetDatabase.LoadAssetAtPath<Texture>("Asset/unity.png")))
            {
                Debug.Log($"GameObject clicked:{Selection.activeGameObject.name}");
            }
        }

        // 处理鼠标事件,弹出我们自己的菜单
        if (Event.current != null && selectionRect.Contains(Event.current.mousePosition))
        {
            Debug.Log($"button:{Event.current.button}, type:{Event.current.type}");
            if (Event.current.button == 1 && Event.current.type <= EventType.MouseUp)
            {
                GameObject selectedGameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;
                if (selectedGameObject)
                {
                    Vector2 mousePos = Event.current.mousePosition;
                    // 弹出 Window/Test 菜单路径下的菜单集合
                    EditorUtility.DisplayPopupMenu(new Rect(mousePos.x, mousePos.y, 0, 0), "Window/Test", null);
                    Event.current.Use();
                }
            }
        }
    }

    [MenuItem("Window/Test/A")]
    static void A()
    {
        Debug.Log("run A");
    }

    [MenuItem("Window/Test/B")]
    static void B()
    {
        Debug.Log("run B");
    }

    [MenuItem("Window/Test/C/c")]
    static void C()
    {
        Debug.Log("run C");
    }

    /// <summary>
    /// 覆写系统的创建 Image 的菜单功能
    /// </summary>
    [MenuItem("GameObject/UI/Image")]
    static void CreateImage()
    {
        if(Selection.activeTransform)
        {
            if(Selection.activeTransform.GetComponentInParent<Canvas>())
            {
                Image img = new GameObject("image").AddComponent<Image>();
                img.raycastTarget = false;
                img.transform.SetParent(Selection.activeTransform, false);
                Selection.activeTransform = img.transform;
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值