What are your feelings

  • Happy
  • Normal
  • Sad

Unity编辑器扩展完整指南

Unity编辑器扩展完整指南

Unity编辑器扩展是一个强大的功能,可以让开发者自定义Unity编辑器的界面和行为,从而提高工作效率。以下是完整指南:

1. 基础知识

1.1 编辑器脚本

  • 编辑器扩展脚本需要放在 Assets/Editor 文件夹或其子文件夹中。

  • 必须引用 UnityEditor 命名空间,例如:

    using UnityEditor;

1.2 常用类

  • Editor: 用于自定义组件的 Inspector 界面。

  • EditorWindow: 创建独立的编辑器窗口。

  • PropertyDrawer: 自定义属性的显示方式。

  • EditorGUILayoutGUILayout: 用于创建自定义的用户界面。


2. 自定义Inspector

通过继承 Editor 类自定义组件的 Inspector 界面。

using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor
{
   public override void OnInspectorGUI()
  {
       // 获取目标对象
       MyComponent myComponent = (MyComponent)target;

       // 添加自定义的GUI控件
       myComponent.myValue = EditorGUILayout.IntField("My Value", myComponent.myValue);

       if (GUILayout.Button("点击执行"))
      {
           Debug.Log("按钮被点击");
      }

       // 处理原Inspector
       DrawDefaultInspector();
  }
}

3. 创建自定义编辑器窗口

通过继承 EditorWindow 创建独立窗口。

using UnityEditor;
using UnityEngine;

public class MyEditorWindow : EditorWindow
{
  [MenuItem("Window/My Editor Window")]
   public static void ShowWindow()
  {
       GetWindow<MyEditorWindow>("My Window");
  }

   private void OnGUI()
  {
       GUILayout.Label("自定义窗口", EditorStyles.boldLabel);

       if (GUILayout.Button("执行操作"))
      {
           Debug.Log("操作执行中...");
      }
  }
}

4. 自定义属性绘制

通过继承 PropertyDrawer 自定义属性字段的显示方式。

using UnityEditor;
using UnityEngine;

public class MyCustomAttribute : PropertyAttribute { }

[CustomPropertyDrawer(typeof(MyCustomAttribute))]
public class MyCustomDrawer : PropertyDrawer
{
   public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
  {
       EditorGUI.BeginProperty(position, label, property);

       property.intValue = EditorGUI.IntSlider(position, label, property.intValue, 0, 100);

       EditorGUI.EndProperty();
  }
}

5. 添加菜单项

使用 MenuItem 创建菜单项。

using UnityEditor;
using UnityEngine;

public class MenuItems
{
  [MenuItem("Tools/My Tool")]
   public static void MyTool()
  {
       Debug.Log("工具被点击");
  }
}

6. Inspector中的拖拽支持

使用 DragAndDrop API 实现拖拽功能。

private void OnGUI()
{
   Event evt = Event.current;

   if (evt.type == EventType.DragUpdated || evt.type == EventType.DragPerform)
  {
       DragAndDrop.visualMode = DragAndDropVisualMode.Copy;

       if (evt.type == EventType.DragPerform)
      {
           DragAndDrop.AcceptDrag();
           foreach (var obj in DragAndDrop.objectReferences)
          {
               Debug.Log("拖拽对象: " + obj.name);
          }
      }
       Event.current.Use();
  }
}

7. SceneView 扩展

通过订阅 SceneView.duringSceneGui 自定义场景视图中的行为。

using UnityEditor;
using UnityEngine;

[InitializeOnLoad]
public class SceneViewExtension
{
   static SceneViewExtension()
  {
       SceneView.duringSceneGui += OnSceneGUI;
  }

   private static void OnSceneGUI(SceneView sceneView)
  {
       Handles.BeginGUI();

       if (GUILayout.Button("场景中的按钮"))
      {
           Debug.Log("场景按钮被点击");
      }

       Handles.EndGUI();
  }
}

8. 处理资源

通过 AssetDatabase 管理资源。

  • 加载资源:

    Object asset = AssetDatabase.LoadAssetAtPath<Object>("Assets/MyAsset.asset");
  • 查找资源:

    string[] guids = AssetDatabase.FindAssets("t:Texture");

9. 性能优化建议

  • 避免在 OnGUI 中执行复杂的逻辑。

  • 使用缓存减少不必要的资源加载。

  • 优化自定义控件的绘制代码,尽量减少GC。


10. 常用工具和资源

  • Unity官方文档:UnityEditor Namespace

  • 社区资源:Unity Asset Store

通过学习和实践以上内容,可以灵活扩展Unity编辑器功能,提高开发效率。

Prompt:

编辑器扩展API

Response:

Unity编辑器扩展API大全

Unity提供了丰富的API来扩展其编辑器的功能,主要分为GUI API自定义Inspector API窗口API场景视图API资源管理API等部分。以下是详细的API分类和示例。


1. GUI API

自定义Inspector、窗口和工具面板时,主要使用以下类和方法。

1.1 EditorGUILayout

  • 作用: 创建自动布局的GUI控件,常用于 OnInspectorGUIOnGUI

  • 常用方法:

    EditorGUILayout.LabelField("标题", EditorStyles.boldLabel);
    myFloat = EditorGUILayout.FloatField("浮点数", myFloat);
    myInt = EditorGUILayout.IntField("整数", myInt);
    myString = EditorGUILayout.TextField("字符串", myString);
    myBool = EditorGUILayout.Toggle("布尔值", myBool);

1.2 EditorGUI

  • 作用: 在自定义 PropertyDrawer 中使用的低级别API,允许精确控制GUI布局。

  • 常用方法:

    EditorGUI.LabelField(position, "标题", EditorStyles.boldLabel);
    myInt = EditorGUI.IntField(position, "整数", myInt);
    myFloat = EditorGUI.FloatField(position, "浮点数", myFloat);

1.3 GUILayout

  • 作用: 适用于 EditorWindow 中的简单布局。

  • 常用方法:

    GUILayout.Label("标题", EditorStyles.boldLabel);
    if (GUILayout.Button("点击按钮"))
    {
       Debug.Log("按钮被点击");
    }

2. 自定义Inspector API

用于自定义组件的 Inspector 界面。

2.1 CustomEditor

  • 作用: 通过继承 Editor 类,重写 OnInspectorGUI 方法。

  • 示例:

    [CustomEditor(typeof(MyComponent))]
    public class MyComponentEditor : Editor
    {
       public override void OnInspectorGUI()
      {
           DrawDefaultInspector();
           if (GUILayout.Button("点击我"))
          {
               Debug.Log("按钮被点击");
          }
      }
    }

3. 自定义窗口 API

用于创建工具窗口和弹出窗口。

3.1 EditorWindow

  • 作用: 自定义工具窗口。

  • 常用方法:

    public class MyWindow : EditorWindow
    {
      [MenuItem("Window/My Tool")]
       public static void ShowWindow()
      {
           GetWindow<MyWindow>("My Tool");
      }

       private void OnGUI()
      {
           GUILayout.Label("这是一个自定义窗口", EditorStyles.boldLabel);
      }
    }

4. 自定义属性绘制API

用于自定义 PropertyAttributePropertyDrawer

4.1 PropertyDrawer

  • 作用: 自定义属性的外观,通常与 PropertyAttribute 配合使用。

  • 示例:

    public class MyCustomAttribute : PropertyAttribute { }

    [CustomPropertyDrawer(typeof(MyCustomAttribute))]
    public class MyCustomDrawer : PropertyDrawer
    {
       public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
      {
           EditorGUI.IntSlider(position, property, 0, 100, label);
      }
    }

5. 场景视图 API

在 SceneView 中自定义工具和可视化内容。

5.1 SceneView

  • 作用: 通过 SceneView.duringSceneGui 修改场景视图。

  • 常用方法:

    [InitializeOnLoad]
    public class SceneViewExample
    {
       static SceneViewExample()
      {
           SceneView.duringSceneGui += OnSceneGUI;
      }

       private static void OnSceneGUI(SceneView sceneView)
      {
           Handles.BeginGUI();
           if (GUILayout.Button("场景中的按钮"))
          {
               Debug.Log("场景按钮被点击");
          }
           Handles.EndGUI();
      }
    }

5.2 Handles

  • 作用: 在场景中绘制可视化控件和工具。

  • 常用方法:

    Handles.DrawLine(startPoint, endPoint);
    Handles.DrawWireCube(center, size);
    Handles.color = Color.red;
    Handles.SphereHandleCap(0, position, Quaternion.identity, 1.0f, EventType.Repaint);

6. 资源管理 API

处理资源的加载、保存和操作。

6.1 AssetDatabase

  • 作用: 管理项目资源的加载和查询。

  • 常用方法:

    // 加载资源
    Texture2D texture = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/Textures/texture.png");

    // 查找资源
    string[] guids = AssetDatabase.FindAssets("t:Texture");
    foreach (string guid in guids)
    {
       string path = AssetDatabase.GUIDToAssetPath(guid);
       Debug.Log(path);
    }

    // 刷新资源
    AssetDatabase.Refresh();

6.2 EditorUtility

  • 作用: 显示对话框、选择文件、保存文件等操作。

  • 常用方法:

    // 显示信息对话框
    EditorUtility.DisplayDialog("标题", "这是信息内容", "确认");

    // 显示文件选择对话框
    string path = EditorUtility.OpenFilePanel("选择文件", "", "txt");

7. 自定义菜单 API

为Unity菜单添加自定义选项。

7.1 MenuItem

  • 作用: 在Unity顶部菜单栏中创建自定义项。

  • 示例:

    public class CustomMenu
    {
      [MenuItem("Tools/自定义工具/执行操作")]
       public static void ExecuteAction()
      {
           Debug.Log("操作已执行");
      }
    }

8. 事件 API

  • Event: 获取当前的GUI事件。

    Event e = Event.current;
    if (e.type == EventType.MouseDown && e.button == 0)
    {
       Debug.Log("鼠标左键被点击");
    }
  • DragAndDrop: 处理拖放操作。

    if (Event.current.type == EventType.DragUpdated)
    {
       DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
    }

9. 热键 API

  • MenuItem热键: 使用 MenuItem 为快捷键定义操作。

    [MenuItem("Tools/快捷键操作 %g")] // % 是 Ctrl,# 是 Shift,& 是 Alt
    public static void ShortcutAction()
    {
       Debug.Log("快捷键 Ctrl+G 被触发");
    }

10. 其他常用API

API 功能 示例
Selection 选择的对象 Selection.activeObject
PrefabUtility 预制体的操作 PrefabUtility.InstantiatePrefab
EditorPrefs 保存/加载用户首选项 EditorPrefs.SetInt("key", 1)
PlayerSettings 项目设置 PlayerSettings.companyName
EditorCoroutine 在编辑器中运行协程 EditorCoroutineUtility.StartCoroutine

参考资源

  • Unity官方文档: UnityEditor Namespace

  • Unity API文档: Unity API Reference

  • Unity GitHub示例: Unity Examples

 

索引