• Unity编辑器拓展最全实现


    1编辑器顶部菜单学习

     验证事项

    2编辑器Scene菜单学习 

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. public class TestSceneMenu : MonoBehaviour
    6. {
    7. [InitializeOnLoadMethod] //加入这个属性,就相当于在编辑器启动的时候执行
    8. static void Ind() {
    9. UnityEditor.SceneView.duringSceneGui += (u) =>
    10. {
    11. //在Scene窗口绘制菜单,只需要在DuringSceneGui绑入一个事件即可
    12. if (Event.current != null &&Event.current.button == 1 && Event.current.type == EventType.MouseUp){
    13. //if里面是描述鼠标右键事件按下,
    14. Rect position = new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y-100,100,100);
    15. //描绘菜单的Rect方框的位置
    16. GUIContent[] contens = new GUIContent[] { new GUIContent("Test1"),new GUIContent("先锋/Test2")};
    17. //菜单里面的按钮数组
    18. EditorUtility.DisplayCustomMenu(position, contens,-1,(data, opt, select)=> {
    19. Debug.LogFormat("data:{0},opt:{1},select:{2},value:{3}",data,opt,select,opt[select]);
    20. },null);
    21. //这是描绘菜单按钮所需要传入的属性,(位置,按钮数组,是否选择(传入按钮数组没有的下标代表不选择),每个按钮所需要处理的点击回调,一般传入空值即可)
    22. Event.current.Use(); //将鼠标复原到指针icon
    23. }
    24. };
    25. }
    26. }

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

    4Assets菜单栏拓展

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. public class TestProject : MonoBehaviour
    6. {
    7. [MenuItem("Assets/Test1")]
    8. static void Test1()
    9. {
    10. Debug.Log("Assets Test1");
    11. //Project文件夹下的按钮,直接把路径改成Assects即可
    12. }
    13. ///
    14. /// 在资源右侧加上按钮
    15. ///
    16. [InitializeOnLoadMethod]
    17. static void InitializeOnLoad()
    18. {
    19. //这个是在Project的窗口创建按钮 guid是Assects下所有资源的唯一标识符
    20. //rect每个资源所占的选中方框大小,
    21. EditorApplication.projectWindowItemOnGUI += (guid, rect) =>
    22. {
    23. //是否选中资源
    24. if (Selection.activeObject != null)
    25. {
    26. //获取资源的GUID唯一标识符
    27. string Select_guid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(Selection.activeObject));
    28. //判断传入的唯一标识符和点击的唯一标识符是否一致
    29. if (guid == Select_guid&&!string.IsNullOrEmpty (Select_guid))
    30. {
    31. //按照所占方框去创建按钮大小
    32. rect.x = rect.width - 100;
    33. rect.width = 100;
    34. if (GUI.Button(rect, "delect"))
    35. {
    36. //删除资源方法
    37. AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(Selection.activeObject));
    38. Debug.LogFormat("资源唯一标识符:{0}", Select_guid);
    39. }
    40. }
    41. }
    42. };
    43. }
    44. }

     5Project事件介绍

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. public class TestProjectEvent : UnityEditor.AssetModificationProcessor
    6. {
    7. ///
    8. /// 将要创建资源的会执行的方法
    9. ///
    10. ///
    11. public static void OnWillCreateAsset(string Path)
    12. {
    13. Debug.LogFormat("创建资源{0}", Path);
    14. }
    15. ///
    16. /// 点击Apply保存资源所执行的方法
    17. ///
    18. ///
    19. ///
    20. public static string[] OnWillSaveAssets(string[] paths)
    21. {
    22. for (int i = 0; i < paths.Length; i++)
    23. {
    24. Debug.LogFormat("保存的资源{0}", paths[i]);
    25. }
    26. return paths;
    27. }
    28. ///
    29. /// 移动资源所执行的方法
    30. ///
    31. ///
    32. ///
    33. ///
    34. public static AssetMoveResult OnWillMoveAsset(string OldPath, string NewPath)
    35. {
    36. Debug.LogFormat("移动资源从{0}到{1}", OldPath, NewPath);
    37. ///需要返回枚举
    38. return AssetMoveResult.DidNotMove; //允许移动
    39. //return AssetMoveResult.DidMove; //不允许移动
    40. //return AssetMoveResult.FailedMove; //不允许移动
    41. }
    42. ///
    43. /// 删除资源所执行的方法 删除资源的路径,操作的枚举,枚举中表述的是删除之后是否进入回收站
    44. ///
    45. ///
    46. ///
    47. ///
    48. public static AssetDeleteResult OnWillDeleteAsset(string path, RemoveAssetOptions opt)
    49. {
    50. Debug.LogFormat("删除资源:{0} options:{1}", path, opt);
    51. return AssetDeleteResult.DidNotDelete; //可以删除
    52. //return AssetDeleteResult.DidDelete; //不能删除
    53. //return AssetDeleteResult.FailedDelete; //不能删除
    54. }
    55. ///
    56. /// 这个标头是项目初始化,监听资源发生变化
    57. ///
    58. [InitializeOnLoadMethod]
    59. static void InitOnLoad()
    60. {
    61. ///根据不同回调监听不同界面的资源回调
    62. EditorApplication.projectChanged += () =>
    63. {
    64. Debug.Log("资源发生改变");
    65. };
    66. EditorApplication.hierarchyChanged+=()=> {
    67. Debug.Log("层级资源发生改变");
    68. };
    69. }
    70. }

    6层级面板的拓展

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. public class TestHierarchy : MonoBehaviour
    6. {
    7. ///
    8. /// 层级面板右键按钮拓展
    9. ///
    10. [MenuItem("GameObject/Test2", false, 0)]
    11. public static void Test2()
    12. {
    13. Debug.Log("GameObject Test2");
    14. }
    15. ///
    16. /// 在层级资源右侧加上按钮
    17. ///
    18. [InitializeOnLoadMethod]
    19. static void InitializeOnLoad()
    20. {
    21. //这个是在Hierarchy的资源左侧创建按钮 InstancesID是Hierarchy下所有资源的唯一ID
    22. //rect每个资源所占的选中方框大小,
    23. EditorApplication.hierarchyWindowItemOnGUI += (InstancesID, rect) =>
    24. {
    25. //是否选中资源 判断选择的资源id和传入的ID是否相等
    26. if (Selection.activeObject != null&&InstancesID==Selection.activeObject.GetInstanceID())
    27. {
    28. //按照所占方框去创建按钮大小
    29. rect.x = rect.width - 50;
    30. rect.width = 100;
    31. if (GUI.Button(rect, "delect"))
    32. {
    33. //删除资源方法
    34. GameObject.DestroyImmediate(Selection.activeObject);
    35. Debug.LogFormat("删除资源:{0}", InstancesID);
    36. }
    37. }
    38. };
    39. }
    40. }

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

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. public class TestMenuOverride
    6. {
    7. [InitializeOnLoadMethod]
    8. static void InitOnLoad() {
    9. ///监听鼠标在层级面板窗口
    10. EditorApplication.hierarchyWindowItemOnGUI += (InstanceID, rect) =>
    11. {
    12. if (Event.current != null)
    13. {
    14. ///判断右键抬起
    15. if (Event.current.button == 1 && Event.current.type == EventType.MouseUp)
    16. {
    17. //阻断本身的右键菜单展出
    18. //Event.current.Use();
    19. //创建自己的菜单按钮,可以看到本身自己的菜单,在”先锋“的地方传入自己的菜单名称即可
    20. //EditorUtility.DisplayPopupMenu(new Rect(Event.current.mousePosition.x, Event.current.mousePosition.y, 100, 100)
    21. // ,"先锋",null);
    22. Debug.Log("鼠标抬起");
    23. }
    24. }
    25. };
    26. }
    27. }

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

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. ///
    6. /// CustomEditor属性指定类型,下面就是在Camera组件加入按钮
    7. ///
    8. [CustomEditor(typeof(Camera))]
    9. public class TestInspector : Editor
    10. {
    11. public override void OnInspectorGUI()
    12. {
    13. base.OnInspectorGUI(); //保持原生的组件属性
    14. ///加入按钮,并且监听按钮按下
    15. if (GUILayout.Button("Test1")){
    16. Debug.Log("雨一直下,气氛不算融化ikun");
    17. ///获取目标组件
    18. Camera c = this.target as Camera;
    19. if (c != null) {
    20. c.fieldOfView = 10;
    21. }
    22. }
    23. }
    24. }

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

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. public class TestInspectorContext : MonoBehaviour
    6. {
    7. ///
    8. /// 命名规则 CONTEXT/组件名字(代码名字)/按钮名字)
    9. ///
    10. ///
    11. [MenuItem("CONTEXT/Transform/Test1")]
    12. static void SetPosition(MenuCommand command) {
    13. Transform transform = command.context as Transform;
    14. if (transform != null) {
    15. transform.position = Vector3.zero;
    16. Debug.Log("重置位置");
    17. }
    18. }
    19. }

    10Scene视图拓展(Gizmos画图)

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. public class TestScene : MonoBehaviour
    5. {
    6. #if UNITY_EDITOR
    7. public Color color;
    8. ///
    9. /// 选中才绘制
    10. ///
    11. private void OnDrawGizmosSelected()
    12. {
    13. Gizmos.DrawLine(transform .position,transform .position +Vector3 .up);
    14. Gizmos.color = color;
    15. Gizmos.DrawSphere(transform.position ,1);
    16. }
    17. ///
    18. /// 一直绘制
    19. ///
    20. private void OnDrawGizmos()
    21. {
    22. //Gizmos.DrawLine(transform.position, transform.position + Vector3.up);
    23. //Gizmos.color = color;
    24. //Gizmos.DrawSphere(transform.position, 1);
    25. }
    26. #endif
    27. }

    11在Scene视图加UI

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. [CustomEditor(typeof(TestScene))]
    6. public class TestSceneGUI : Editor
    7. {
    8. private void OnSceneGUI()
    9. {
    10. Handles.BeginGUI(); //3d中开始2D块
    11. if (GUILayout.Button("TestScene",GUILayout.Width (100))) {
    12. Debug.Log("This TestScene");
    13. }
    14. Handles.EndGUI();
    15. }
    16. }

    12在Scene视图加固定的UI

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. [CustomEditor(typeof(TestScene))]
    6. public class TestSceneGUI : Editor
    7. {
    8. private void OnSceneGUI()
    9. {
    10. Handles.BeginGUI(); //3d中开始2D块
    11. if (GUILayout.Button("TestScene",GUILayout.Width (100))) {
    12. Debug.Log("This TestScene");
    13. }
    14. Handles.EndGUI();
    15. }
    16. [InitializeOnLoadMethod]
    17. static void InitLoad() {
    18. //代码启动就开始画UI
    19. SceneView.duringSceneGui += (sceneView) =>
    20. {
    21. Handles.BeginGUI(); //3d中开始2D块
    22. //按钮
    23. if (GUILayout.Button("Test2", GUILayout.Width(100)))
    24. {
    25. Debug.Log("This TestScene");
    26. }
    27. //标签
    28. GUILayout.Label("先锋");
    29. Handles.EndGUI();
    30. };
    31. }
    32. }

    13Game视图增加拓展

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. ///
    5. /// 这个特性运行在编辑器下,不需要运行就能出现按钮,如果
    6. /// 不加属性,需要运行才会出现在Game视图(需要将代码挂载到物体上)
    7. ///
    8. [ExecuteInEditMode]
    9. public class TestGame : MonoBehaviour
    10. {
    11. private void OnGUI()
    12. {
    13. if (GUILayout.Button("Test1",GUILayout.Width(100))) {
    14. Debug.Log("Test Scene");
    15. }
    16. }
    17. }

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

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. public class TestWindow : EditorWindow
    6. {
    7. ///
    8. /// 在窗口中创建一个按钮
    9. ///
    10. private void OnGUI()
    11. {
    12. if (GUILayout.Button("创建对象")) {
    13. Debug.Log("创建模型");
    14. }
    15. }
    16. //以下都是生命周期
    17. ///
    18. /// 窗口启动
    19. ///
    20. private void Awake()
    21. {
    22. Debug.Log("Awake");
    23. }
    24. ///
    25. /// 窗口销毁
    26. ///
    27. private void OnDestroy()
    28. {
    29. Debug.Log("OnDestroy");
    30. }
    31. ///
    32. /// 鼠标焦点,当鼠标出去再进来会执行一次
    33. ///
    34. private void OnFocus()
    35. {
    36. Debug.Log("OnFocus");
    37. }
    38. ///
    39. /// 窗口常输出
    40. ///
    41. private void Update()
    42. {
    43. Debug.Log("Update");
    44. }
    45. }

    创建一个按钮打开窗口

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

    效果图

     

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

    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5. public class TestPreview : EditorWindow
    6. {
    7. Object Obj; //
    8. Editor PreviewObj;
    9. Object LatsObj;
    10. ///
    11. /// 创建一个文件输入窗口
    12. ///
    13. private void OnGUI()
    14. {
    15. //可以在这里点击输出框
    16. Obj=EditorGUILayout.ObjectField(Obj,typeof(Object),false);
    17. //创建一个窗口
    18. if (Obj!=null&&Obj!= LatsObj) {
    19. PreviewObj = Editor.CreateEditor(Obj);
    20. LatsObj = Obj;
    21. }
    22. //创建预览画面
    23. if (PreviewObj != null) {
    24. PreviewObj.OnPreviewGUI(GUILayoutUtility.GetRect(400, 400), EditorStyles.label);
    25. }
    26. }
    27. ///
    28. /// 打开预览窗口
    29. ///
    30. [MenuItem("先锋/预览窗口")]
    31. static void Test3() {
    32. TestPreview tp = EditorWindow.GetWindow();
    33. tp.Show();
    34. }
    35. }

     效果实现

     

  • 相关阅读:
    Git多分支 远程仓库 协同开发以及解决冲突
    26-SpringBoot 缓存
    Python 程序性能测试方法
    spring boot 配置加载顺序
    华为云云耀云服务器L实例评测 | 实例使用教学之软件安装:华为云云耀云服务器环境下安装 Docker
    原生微信小程序引入离线iconfont字体图标
    微擎模块 志汇同城微圈小程序10.9.5开源版
    C++学习第二十九天----引用变量和c语言之register关键字
    时序预测 | MATLAB实现TCN时间卷积神经网络的时间序列预测
    java-python高校大学教室管理系统
  • 原文地址:https://blog.csdn.net/qq_37335907/article/details/128013656