关键词搜索

源码搜索 ×
×

unity 编辑器扩展简单入门

发布2022-06-18浏览546次

详情内容

c#教程icon-default.png?t=M5H6https://www.jxasp.com/blog

通过使用编辑器扩展,我们可以对一些机械的操作实现自动化,而不用使用额外的环境,将工具与开发环境融为一体;并且,编辑器扩展也提供GUI库,来实现可视化操作;编辑器扩展甚至也可以“补充”IDE缺失的一些内容,让IDE更加人性化。
 

主要内容

  • MenuItem无界面操作
  • 窗口
  • 优化内置操作
  • 简单工具窗口
  • Gizmos改造场景显示

一、MenuItem无界面操作


在 assets文件夹下创建Editor文件夹,创建一个新的c#脚本;

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. public class BaseTest : MonoBehaviour
  6. {
  7. [MenuItem("德玛/第一个扩展")]
  8. static void debugLog()
  9. {
  10. Debug.Log("我是一个menuItem");
  11. }
  12. }

如图,这是我们第一个创建的扩展。

此时,如果我们需要获得一个当前场景选中的物品,则
需要通过Selection。将代码拷贝到当前创建的类里面:

  1. // 设置第二个参数
  2. [MenuItem("德玛/two", false)]
  3. static void testSecondParam()
  4. {
  5. Vector3 p = Selection.activeTransform.position;
  6. Vector3 v3 = new Vector3(p.x+1, p.y, p.z);
  7. Instantiate(Selection.activeTransform, v3, Quaternion.identity);
  8. }
  9. [MenuItem("德玛/two", true)]
  10. static bool testSecondParam2()
  11. {
  12. return Selection.activeGameObject != null;
  13. }

通过这段代码,我们可以创建一个只有选择了一个场景物体,才会激活的按钮。

二、窗口


创建窗口需要通过EditorWindow作为基类,还是MenuItem为入口创建;

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor; //注意要引用
  4. public class MyWindow : EditorWindow
  5. {
  6. [MenuItem("德玛/Window/NormalWindow")]//在unity菜单Window下有MyWindow选项
  7. static void NormalWindow()
  8. {
  9. windowType = 1;
  10. MyWindow myWindow = (MyWindow)EditorWindow.GetWindow(typeof(MyWindow), true, "德玛标题", true);//创建窗口
  11. myWindow.Show();//展示
  12. }
  13. public void Awake()
  14. {
  15. //在资源中读取一张贴图
  16. texture = Resources.Load("1") as Texture;
  17. }
  18. //绘制窗口时调用
  19. void OnGUI()
  20. {
  21. EditorGUILayout.LabelField("选中");
  22. EditorGUILayout.LabelField(EditorWindow.focusedWindow.ToString());
  23. EditorGUILayout.LabelField("划入");
  24. EditorGUILayout.LabelField(EditorWindow.mouseOverWindow.ToString());
  25. }
  26. //更新
  27. void Update()
  28. {
  29. }
  30. void OnFocus()
  31. {
  32. Debug.Log("当窗口获得焦点时调用一次");
  33. }
  34. void OnLostFocus()
  35. {
  36. Debug.Log("当窗口丢失焦点时调用一次");
  37. }
  38. void OnHierarchyChange()
  39. {
  40. Debug.Log("当Hierarchy视图中的任何对象发生改变时调用一次");
  41. }
  42. void OnProjectChange()
  43. {
  44. Debug.Log("当Project视图中的资源发生改变时调用一次");
  45. }
  46. void OnInspectorUpdate()
  47. {
  48. //Debug.Log("窗口面板的更新");
  49. //这里开启窗口的重绘,不然窗口信息不会刷新
  50. this.Repaint();
  51. }
  52. void OnSelectionChange()
  53. {
  54. //当窗口出去开启状态,并且在Hierarchy视图中选择某游戏对象时调用
  55. foreach (Transform t in Selection.transforms)
  56. {
  57. //有可能是多选,这里开启一个循环打印选中游戏对象的名称
  58. Debug.Log("OnSelectionChange" + t.name);
  59. }
  60. }
  61. void OnDestroy()
  62. {
  63. Debug.Log("当窗口关闭时调用");
  64. }
  65. }

将上面的代码放入Editor目录下,通过德玛/Window/NormalWindow可以打开窗口。
EditorWindow.focusedWindow获取当前焦点窗口;
EditorWindow.mouseOverWindow获取当前鼠标划入的窗口;

各种生命周期函数均有打印,自行理会。

  1. void OnInspectorUpdate()
  2. {
  3. //Debug.Log("窗口面板的更新");
  4. //这里开启窗口的重绘,不然窗口信息不会刷新
  5. this.Repaint();
  6. }

这段代码可以保证实时刷新显示。

三、优化内置操作


当路径放入GameObject的时候,会出现在右键菜单里面;

  [MenuItem("GameObject/德玛/德玛Custom Game Object", false, 10]

注解

当然,除了在Editor目录下添加各种扩展以外,我们可以通过给项目脚本添加注解的方式,来优化编辑器显示;
比如通过添加类似于Component的方式,来优化脚本的添加方式,点击后会直接将脚本添加到场景物体上。
[RequireComponent(typeof(Rigidbody))]放入类头。我们将下面脚本放入到Assets/Scripts目录下面。

  1. using UnityEngine;
  2. // 通过编辑器的Component菜单添加脚本
  3. [RequireComponent(typeof(Rigidbody))]
  4. [HelpURL("https://docs.unity3d.com/ScriptReference/HelpURLAttribute.html")]
  5. [AddComponentMenu("德玛/添加德玛脚本")]
  6. public class ContextTesting : MonoBehaviour
  7. {
  8. [Header("属性标题")]
  9. [Multiline(3)]
  10. public string name2;
  11. [Space(100)]
  12. [Tooltip("用于设置性别")]
  13. public string sex;
  14. [HideInInspector]
  15. public int p = 5;
  16. [Range(1, 100)]
  17. [Tooltip("Health value between 0 and 100.")]
  18. public int health = 0;
  19. /// Add a context menu named "Do Something" in the inspector
  20. /// of the attached script.
  21. /// 给当前脚本添加右键内容
  22. [ContextMenu("德玛西亚")]
  23. void DoSomething()
  24. {
  25. Debug.Log("德玛西亚打印");
  26. }
  27. // 给属性添加右键
  28. [ContextMenuItem("重置属性为空", "ResetBiography")]
  29. public string playerBiography = "";
  30. void ResetBiography()
  31. {
  32. playerBiography = "";
  33. }
  34. }

我们发现,我们可以想组件一样的添加脚本了!


Inspector目录我们也注意到当前脚本属性的显示也发生了变化;

Inspector上,我们也多出来一个Rigidbody组件。

美化项目脚本的属性显示

Assets/Scripts下面创建MyPlayer

  1. using UnityEngine;
  2. using System.Collections;
  3. public class MyPlayer : MonoBehaviour
  4. {
  5. public int armor = 100;
  6. public int attack = 100;
  7. public GameObject equipment;
  8. }

Editor下面创建MyPlayerEditor:

  1. using UnityEngine;
  2. using UnityEditor;
  3. using System.Collections;
  4. [CustomEditor(typeof(MyPlayer))]
  5. public class MyPlayerEditor : Editor
  6. {
  7. SerializedProperty attack;
  8. void OnEnable()
  9. {
  10. attack = serializedObject.FindProperty("attack");
  11. }
  12. public override void OnInspectorGUI()
  13. {
  14. serializedObject.Update();
  15. EditorGUILayout.IntSlider(attack, 0, 100, new GUIContent("攻击力"));
  16. ProgressBar(attack.intValue / 100, "攻击力");
  17. serializedObject.ApplyModifiedProperties();
  18. }
  19. private void ProgressBar(float value, string label)
  20. {
  21. Rect rect = GUILayoutUtility.GetRect(18, 18, "TextField");
  22. EditorGUI.ProgressBar(rect, value, label);
  23. EditorGUILayout.Space();
  24. }
  25. }

观察Inspector

简单工具窗口


一个简单的确认窗口

  1. using UnityEngine;
  2. using UnityEditor;
  3. public class MyEditorUtilityTest : ScriptableObject
  4. {
  5. [MenuItem("德玛/自定义对话框")]
  6. static void CreateWizard()
  7. {
  8. if (EditorUtility.DisplayDialog("对话框标题", "对话框的消息", "OK", "取消"))
  9. {
  10. Debug.Log("OK被点击");
  11. }
  12. else
  13. {
  14. Debug.Log("您没有点击OK");
  15. }
  16. }
  17. }

显示如下

Gizmos改造场景显示


我们可以改造物体在场景中的显示;

如下代码

其他


通过上面的案例,我们大致了解了Unity编辑器扩展的基本内容,通过这些已经可以实现很多功能了!

仓库地址:
GitHub - wyy5552/unityEditor: unity 编辑器

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载