扩展默认组件和资源的 Inspector 视图
之前介绍的扩展方法都是扩展自定义创建的脚本对应的 Inspector 面板,实际上开发者也可以通过一些方法来扩展 Unity 内部的组件或者资源对应的 Inspector 面板。
扩展默认组件
这里以扩展 Unity 内置的 Camera 组件为例,在不修改原有控件的前提下扩展 Camera 组件,增加一个随机设置位置的简单功能。
在空场景中添加一个名为 Camera
的物体,然后在 Inspector 中添加一个 Camera 组件:
首先实现该主要功能,即在一个确定的范围内随机产生一个位置,然后将 Camera
的位置修改为该位置:
Vector3 GenerateRandomPosition (float boundX, float boundY, float boundZ) {
return new Vector3 (
Random.Range (-boundX, boundX),
Random.Range (-boundY, boundY),
Random.Range (-boundZ, boundZ)
);
}
void SetCameraPosition (Camera camera, Vector3 position) {
camera.transform.position = position;
}
然后在新建脚本 Tools/DefaultComponents/Editor/CameraExtensionInspector.cs
中添加编辑器类和 Inspector 绘制逻辑:
using UnityEngine;
using UnityEditor;
namespace InspectorExtension.CameraExtensionInspector {
[CustomEditor (typeof (Camera))]
public class CameraExtensionInspector : Editor {
Camera _target;
private void OnEnable () {
_target = (Camera)target;
}
public override void OnInspectorGUI () {
if (GUILayout.Button ("Set Camera Randomly")) {
Vector3 randomPosition = GenerateRandomPosition (10, 10, 10);
SetCameraPosition (_target, randomPosition);
}
}
}
}
编译后发现 Inspector 视图中只绘制了按钮,原本的控件都不见了,原因是自定义的绘制代码将会覆盖原有的绘制过程:
为不影响原控件的绘制,需要在自定义的绘制代码中添加原有的绘制过程:
public override void OnInspectorGUI () {
base.DrawDefaultInspector ();
if (GUILayout.Button ("Set Camera Randomly")) {
Vector3 randomPosition = GenerateRandomPosition (10, 10, 10);
SetCameraPosition (_target, randomPosition);
}
}
此时编译后 Inspector 试图如下:
根据之前扩展 Inspector 面板的实例可知,新的绘制逻辑由重写的 OnInspectorGUI
确定,而哪个组件将被重新绘制,则是由整个类之前的 CustomEditor
属性决定的:
public CustomEditor(Type inspectedType);
public CustomEditor(Type inspectedType, bool editorForChildClasses);
inspectedType
即为对应重新绘制的组件的类型, editorForChildClasses
表示该类型的子类是否也会显示该编辑器。
基于此,实际上可以通过 CustomEditor
扩展各种类型的组件,包括开发者自定义的组件和 Unity 内置的组件。
扩展默认资源
鼠标点击 Project 中的资源或资源文件夹时,Inspector 面板也会有对应不同的显示:
根据之前的讨论,修改 CustomEditor
中的参数即可自定义对应组件的绘制逻辑。同样道理,只要找到这些默认资源对应的类型,就可以扩展其 Inspector 面板。
通过查阅 Unity 官方文档和相关资料,可以得知默认资源对应的类型,下表列举了部分常用的默认资源对应的类:
常用默认资源及其对应类
资源类型 | 对应类 | 文件后缀 |
---|---|---|
场景资源 | SceneAsset | .unity |
图片资源 | TextureImporter | .jpg .png 等 |
音效资源 | AudioImporter | .mp3 .sfx 等 |
脚本资源 | MonoScript | .cs .js .lua 等 |
文件夹或暂无确定类型的资源 | DefaultAsset | 无文件后缀或 Unity 无法识别的后缀 |
将默认资源对应的类的类型以参数的形式传入 CustomEditor
后,即可通过重写绘制函数自定义修改 Inspector 视图。作为一个例子,现对场景资源的 Inspector 面板进行简单的自定义:
using UnityEditor;
namespace InspectorExtension.DefaultAssets {
[CustomEditor (typeof (SceneAsset))]
public class DefaultAssetsInspector : Editor {
SceneAsset _target;
private void OnEnable () {
_target = (SceneAsset)target;
}
public override void OnInspectorGUI () {
EditorGUILayout.HelpBox ("This is a Unity scene named \"" + _target.name + "\".", MessageType.None);
}
}
}