Unity编辑器拓展最全实现

Posted 一丁目赠我

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity编辑器拓展最全实现相关的知识,希望对你有一定的参考价值。

1编辑器顶部菜单学习

 验证事项

2编辑器Scene菜单学习 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestSceneMenu : MonoBehaviour
  

    [InitializeOnLoadMethod]   //加入这个属性,就相当于在编辑器启动的时候执行
    static void Ind() 
        UnityEditor.SceneView.duringSceneGui += (u) =>
        
            //在Scene窗口绘制菜单,只需要在DuringSceneGui绑入一个事件即可

            if (Event.current != null &&Event.current.button == 1 && Event.current.type == EventType.MouseUp)
                //if里面是描述鼠标右键事件按下,

                Rect position = new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y-100,100,100);
                //描绘菜单的Rect方框的位置

                GUIContent[] contens = new GUIContent[]  new GUIContent("Test1"),new GUIContent("先锋/Test2");
                //菜单里面的按钮数组
                EditorUtility.DisplayCustomMenu(position, contens,-1,(data, opt, select)=> 
                    Debug.LogFormat("data:0,opt:1,select:2,value:3",data,opt,select,opt[select]);
                ,null);

                //这是描绘菜单按钮所需要传入的属性,(位置,按钮数组,是否选择(传入按钮数组没有的下标代表不选择),每个按钮所需要处理的点击回调,一般传入空值即可)

                Event.current.Use();   //将鼠标复原到指针icon
            
        ;
    
    

3编辑器如何给按钮添加快捷键学习

4Assets菜单栏拓展

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestProject : MonoBehaviour




    [MenuItem("Assets/Test1")]
    static void Test1()
    
        Debug.Log("Assets  Test1");
        //Project文件夹下的按钮,直接把路径改成Assects即可
    


    /// <summary>
    /// 在资源右侧加上按钮
    /// </summary>
    [InitializeOnLoadMethod]
    static void InitializeOnLoad()
    

        //这个是在Project的窗口创建按钮   guid是Assects下所有资源的唯一标识符   
        //rect每个资源所占的选中方框大小,
        EditorApplication.projectWindowItemOnGUI += (guid, rect) =>
        

            //是否选中资源
            if (Selection.activeObject != null)
            

                //获取资源的GUID唯一标识符
                string Select_guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(Selection.activeObject));
                //判断传入的唯一标识符和点击的唯一标识符是否一致
                if (guid == Select_guid&&!string.IsNullOrEmpty (Select_guid))
                
                    //按照所占方框去创建按钮大小
                    rect.x = rect.width - 100;
                    rect.width = 100;
                    if (GUI.Button(rect, "delect"))
                    
                        //删除资源方法
                        AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Selection.activeObject));
                        Debug.LogFormat("资源唯一标识符:0", Select_guid);
                    

                

            

        ;
    

 5Project事件介绍

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class TestProjectEvent : UnityEditor.AssetModificationProcessor

    /// <summary>
    /// 将要创建资源的会执行的方法
    /// </summary>
    /// <param name="Path"></param>
    public static void OnWillCreateAsset(string Path)
    
        Debug.LogFormat("创建资源0", Path);
    

    /// <summary>
    /// 点击Apply保存资源所执行的方法
    /// </summary>
    /// <param name="paths"></param>
    /// <returns></returns>
    public static string[] OnWillSaveAssets(string[] paths)
    

        for (int i = 0; i < paths.Length; i++)
        
            Debug.LogFormat("保存的资源0", paths[i]);
        
        return paths;
    


    /// <summary>
    /// 移动资源所执行的方法
    /// </summary>
    /// <param name="OldPath"></param>
    /// <param name="NewPath"></param>
    /// <returns></returns>
    public static AssetMoveResult OnWillMoveAsset(string OldPath, string NewPath)
    

        Debug.LogFormat("移动资源从0到1", OldPath, NewPath);
        ///需要返回枚举
        return AssetMoveResult.DidNotMove;   //允许移动
        //return AssetMoveResult.DidMove;    //不允许移动
        //return AssetMoveResult.FailedMove;   //不允许移动

    


    /// <summary>
    /// 删除资源所执行的方法    删除资源的路径,操作的枚举,枚举中表述的是删除之后是否进入回收站
    /// </summary>
    /// <param name="path"></param>
    /// <param name="opt"></param>
    /// <returns></returns>
    public static AssetDeleteResult OnWillDeleteAsset(string path, RemoveAssetOptions opt)
    


        Debug.LogFormat("删除资源:0  options:1", path, opt);



        return AssetDeleteResult.DidNotDelete;  //可以删除
        //return AssetDeleteResult.DidDelete;   //不能删除
        //return AssetDeleteResult.FailedDelete;   //不能删除
    


    /// <summary>
    /// 这个标头是项目初始化,监听资源发生变化
    /// </summary>
    [InitializeOnLoadMethod]
    static void InitOnLoad()
    

        ///根据不同回调监听不同界面的资源回调
        EditorApplication.projectChanged += () =>
        
            Debug.Log("资源发生改变");
        ;

        EditorApplication.hierarchyChanged+=()=> 
            Debug.Log("层级资源发生改变");
        ;
    



6层级面板的拓展

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestHierarchy : MonoBehaviour


    /// <summary>
    /// 层级面板右键按钮拓展
    /// </summary>
    [MenuItem("GameObject/Test2", false, 0)]
    public static void Test2()
    
        Debug.Log("GameObject  Test2");
        
    

    /// <summary>
    /// 在层级资源右侧加上按钮
    /// </summary>
    [InitializeOnLoadMethod]
    static void InitializeOnLoad()
    

        //这个是在Hierarchy的资源左侧创建按钮   InstancesID是Hierarchy下所有资源的唯一ID  
        //rect每个资源所占的选中方框大小,
        EditorApplication.hierarchyWindowItemOnGUI += (InstancesID, rect) =>
        
            //是否选中资源   判断选择的资源id和传入的ID是否相等
            if (Selection.activeObject != null&&InstancesID==Selection.activeObject.GetInstanceID())
                                           
                    //按照所占方框去创建按钮大小
                    rect.x = rect.width - 50;
                    rect.width = 100;
                    if (GUI.Button(rect, "delect"))
                    
                    //删除资源方法
                    GameObject.DestroyImmediate(Selection.activeObject);
                        Debug.LogFormat("删除资源:0", InstancesID);
                                  
            

        ;
    



7抛弃原来的菜单,重新创建菜单

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestMenuOverride


    [InitializeOnLoadMethod]
    static void InitOnLoad() 
        ///监听鼠标在层级面板窗口
        EditorApplication.hierarchyWindowItemOnGUI += (InstanceID, rect) =>
        
            if (Event.current != null)
            
                ///判断右键抬起
                if (Event.current.button == 1 && Event.current.type == EventType.MouseUp)
                
                    //阻断本身的右键菜单展出
                    //Event.current.Use();

                    //创建自己的菜单按钮,可以看到本身自己的菜单,在”先锋“的地方传入自己的菜单名称即可
                    //EditorUtility.DisplayPopupMenu(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 100, 100)
                      //  ,"先锋",null);

                    Debug.Log("鼠标抬起");                    
                
            

        ;
    


8在Inspector面板组件拓展 (在代码或者组件下面加按钮)

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

/// <summary>
/// CustomEditor属性指定类型,下面就是在Camera组件加入按钮
/// </summary>
[CustomEditor(typeof(Camera))]
public class TestInspector : Editor


    public override void OnInspectorGUI()
    
        base.OnInspectorGUI();  //保持原生的组件属性  

        ///加入按钮,并且监听按钮按下
        if (GUILayout.Button("Test1"))
            Debug.Log("雨一直下,气氛不算融化ikun");

            ///获取目标组件
            Camera c = this.target as Camera;
            if (c != null) 
                c.fieldOfView = 10;
            
        

    


9在Inspector Context组件拓展(组件右键面板加按钮)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestInspectorContext : MonoBehaviour


    /// <summary>
    /// 命名规则   CONTEXT/组件名字(代码名字)/按钮名字)
    /// </summary>
    /// <param name="command"></param>
    [MenuItem("CONTEXT/Transform/Test1")]
    static void SetPosition(MenuCommand command) 

        Transform transform = command.context as Transform;

        if (transform != null) 
            transform.position = Vector3.zero;
            Debug.Log("重置位置");
        
    
    



10Scene视图拓展(Gizmos画图)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestScene : MonoBehaviour


#if UNITY_EDITOR

    public  Color color;

    /// <summary>
    /// 选中才绘制
    /// </summary>
    private void OnDrawGizmosSelected()
    
        Gizmos.DrawLine(transform .position,transform .position +Vector3 .up);
        Gizmos.color = color;
        Gizmos.DrawSphere(transform.position ,1);
    

    /// <summary>
    /// 一直绘制
    /// </summary>
    private void OnDrawGizmos()
    
        //Gizmos.DrawLine(transform.position, transform.position + Vector3.up);
        //Gizmos.color = color;
        //Gizmos.DrawSphere(transform.position, 1);


    
#endif


11在Scene视图加UI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(TestScene))]
public class TestSceneGUI : Editor

    private void OnSceneGUI()
    
        Handles.BeginGUI();    //3d中开始2D块
        if (GUILayout.Button("TestScene",GUILayout.Width (100))) 
            Debug.Log("This TestScene");
        

        Handles.EndGUI();
    

12在Scene视图加固定的UI

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CustomEditor(typeof(TestScene))]
public class TestSceneGUI : Editor

    private void OnSceneGUI()
    
        Handles.BeginGUI();    //3d中开始2D块
        if (GUILayout.Button("TestScene",GUILayout.Width (100))) 
            Debug.Log("This TestScene");
        

        Handles.EndGUI();
    



    [InitializeOnLoadMethod]
    static void InitLoad() 
        //代码启动就开始画UI
        SceneView.duringSceneGui += (sceneView) =>
        
            Handles.BeginGUI();    //3d中开始2D块
            //按钮
            if (GUILayout.Button("Test2", GUILayout.Width(100)))
            
                Debug.Log("This TestScene");
            
            //标签
            GUILayout.Label("先锋");

            Handles.EndGUI();
        ;
    

13Game视图增加拓展

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 这个特性运行在编辑器下,不需要运行就能出现按钮,如果
/// 不加属性,需要运行才会出现在Game视图(需要将代码挂载到物体上)
/// </summary>
[ExecuteInEditMode]
public class TestGame : MonoBehaviour

    private void OnGUI()
    
        if (GUILayout.Button("Test1",GUILayout.Width(100))) 
            Debug.Log("Test Scene");
        
    

14在编辑器下创建自己的窗口

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestWindow : EditorWindow

    /// <summary>
    /// 在窗口中创建一个按钮
    /// </summary>
    private void OnGUI()
    
        if (GUILayout.Button("创建对象")) 
            Debug.Log("创建模型");
        
    


    //以下都是生命周期

    /// <summary>
    /// 窗口启动
    /// </summary>
    private void Awake()
    
        Debug.Log("Awake");
    

    /// <summary>
    /// 窗口销毁
    /// </summary>
    private void OnDestroy()
    
        Debug.Log("OnDestroy");
    

    /// <summary>
    /// 鼠标焦点,当鼠标出去再进来会执行一次
    /// </summary>
    private void OnFocus()
    
        Debug.Log("OnFocus");
    


    /// <summary>
    /// 窗口常输出
    /// </summary>
    private void Update()
    
        Debug.Log("Update");
    

创建一个按钮打开窗口

15窗口中右上角下拉菜单的拓展

效果图

 

 16 在自己创建的Window窗口创建模型预览窗口

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class TestPreview : EditorWindow


    Object Obj;   //
    Editor PreviewObj;

    Object LatsObj;

    /// <summary>
    /// 创建一个文件输入窗口
    /// </summary>
    private void OnGUI()
    
        //可以在这里点击输出框
        Obj=EditorGUILayout.ObjectField(Obj,typeof(Object),false);

        //创建一个窗口
        if (Obj!=null&&Obj!= LatsObj) 
            PreviewObj = Editor.CreateEditor(Obj);
            LatsObj = Obj;
        

        //创建预览画面
        if (PreviewObj != null) 
            PreviewObj.OnPreviewGUI(GUILayoutUtility.GetRect(400, 400), EditorStyles.label);
        
        

    


    /// <summary>
    /// 打开预览窗口
    /// </summary>
    [MenuItem("先锋/预览窗口")]
    static void Test3() 
        TestPreview tp = EditorWindow.GetWindow<TestPreview>();
        tp.Show();
    


 效果实现

 

以上是关于Unity编辑器拓展最全实现的主要内容,如果未能解决你的问题,请参考以下文章

编辑器拓展九——用代码实现unity菜单命令

unity编辑器拓展七——脚本创建模型

UNITY3D拓展编辑器 - 目录

(转 )Unity对Lua的编辑器拓展

Unity编辑器拓展(GraphView制作对话系统编辑器)

Unity编辑器拓展(MenuItem)