【Unity编辑器】拓展Hierarchy视图

目录

1、拓展菜单

2、拓展布局

3、重写菜单


1、拓展菜单

在Hierarchy视图中点击Create按钮,弹出的菜单My Create->Cube就是自定义拓展菜单

using UnityEngine;
using UnityEditor;

public class S2_拓展菜单 : MonoBehaviour
{
    [MenuItem("GameObject/My Create/Cube" , false , 0)]
    static void CreateCube()
    {
        GameObject.CreatePrimitive(PrimitiveType.Cube);
    }
}

菜单中已经包含了系统默认的一些菜单项,我们拓展的原理就是重写MenuItem的自定义路径。Create按钮下的菜单项都在GameOject路径下面,所以只要开头是GameObject/xx/xx,均可自由拓展。

2、拓展布局

选择不同的游戏对象后,在右侧可根据EditorGUI拓展出一组按钮,点击Unity图标后,在Console窗口中输入这个游戏对象。

扫描二维码关注公众号,回复: 15264519 查看本文章

工作原理就是监听EditorApplication.hierarchyWindowItemOnGUI渲染回调

using UnityEditor;
using UnityEngine;

public class S2_拓展布局 : MonoBehaviour
{
    [InitializeOnLoadMethod]
    static void InitializeOnLoadMethod()
    {
        EditorApplication.hierarchyWindowItemOnGUI = delegate (int instanceID, Rect selectionRect)
        {
            //在Hierarchy视图中选择一个资源
            if (Selection.activeObject && instanceID == Selection.activeObject.GetInstanceID())
            {
                //设置拓展按钮区域
                float width = 40f;
                float height = 20f;
                selectionRect.x += (selectionRect.width - width);
                selectionRect.width = width;
                selectionRect.height = height;

                //点击事件
                if (GUI.Button(selectionRect, AssetDatabase.LoadAssetAtPath<Texture>("Assets/unity.png")))
                {
                    Debug.LogFormat("click:{0}", Selection.activeObject.name);
                }
            }
        };
    }
}

在代码中实现EditorApplication.hierarchyWindowItemOnGUI委托,就可以重写Hierarchy视图了。

这里使用GUI.Button来绘制自定义按钮,点击按钮可监听事件。

3、重写菜单

彻底重写菜单

工作原理:监听点击的事件,打开一个新的菜单窗口

使用Event.current来获取当前的事件。当监听到鼠标抬起的事件后,并且满足游戏对象的选中状态,开始执行自定义事件。

EditorUtility.DisplayPopupMenu用于弹出自定义菜单,Event.current.Use()的含义是不再执行原有的操作,所以就实现了重写菜单。

using UnityEngine;
using UnityEditor;
using GluonGui.WorkspaceWindow.Views.WorkspaceExplorer.Explorer;

public class S2_重写菜单
{
    [MenuItem("Window/Test/自定义工具")]
    static void Test()
    {

    }

    [MenuItem("Window/Test/自定义2")]
    static void Test1()
    {

    }

    [MenuItem("Window/Test/自定义3/MOMO")]
    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 selectedGameObject = EditorUtility.InstanceIDToObject(instanceID) as GameObject;

            //这里可以判断selectedGameObject的条件
            if (selectedGameObject)
            {
                Vector2 mousePosition = Event.current.mousePosition;

                EditorUtility.DisplayPopupMenu(new Rect(mousePosition.x, mousePosition.y, 0, 0), "Window/Test", null);	//用于弹出自定义菜单
                Event.current.Use();	//不再执行原有操作,所以实现了重写
            }
        }
    }
}

此外Hierarchy视图还可以重写系统自带的菜单行为。例如:我觉得Image组件不好用,可以复写它的行为。

创建Image组件时,会自动勾选RaycastTarget。如果图片不需要处理点击事件,这样会带来额外开销。

下面就是复写Image组件的逻辑,让RaycastTarget默认不勾选

using UnityEngine;
using UnityEditor;
using UnityEngine.UI;

public class S2_重写组件设置
{
    [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;
            }
        }
    }
}

由于重写了菜单,所以需要通过使用脚本自行创建Image对象和组件。接着,获取到image组件对象,直接设置它的raycastTarget属性即可。

猜你喜欢

转载自blog.csdn.net/weixin_60154963/article/details/130495043