Unity编辑器扩展是一个强大的功能,可以让开发者自定义Unity编辑器的界面和行为,从而提高工作效率。以下是完整指南:
1. 基础知识
1.1 编辑器脚本
-
编辑器扩展脚本需要放在
Assets/Editor
文件夹或其子文件夹中。 -
必须引用
UnityEditor
命名空间,例如:using UnityEditor;
1.2 常用类
-
Editor
: 用于自定义组件的 Inspector 界面。 -
EditorWindow
: 创建独立的编辑器窗口。 -
PropertyDrawer
: 自定义属性的显示方式。 -
EditorGUILayout
和GUILayout
: 用于创建自定义的用户界面。
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控件,常用于
OnInspectorGUI
和OnGUI
。 -
常用方法:
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
用于自定义 PropertyAttribute
和 PropertyDrawer
。
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");
为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示例: