inspector面板
使用EditorGUILayout进行绘制,Editor文件下
成员变量的显示
在成员变量前使用Attribute修改该变量,使其可以在inspector面板上进行序列化
- [SerializeField]:一般修饰 private和protected 变量,来达到序列化私有和保护变量的目的,从而可以在Inspector面板中显示和编辑。防止仅仅想让其在Inspector面板中显示而导致public变量滥用。
- [NonSerialized]:一般修饰public变量,来达到不被序列化的目的,且不在Inspector面板中显示。
- [HideInInspector]:一般修饰public变量,来达到不在Inspector面板中显示的目的
- [Serializable]:用在类的前面,表示该类可被序列化
总结
- 被序列化的值可以在Inspector面板上显示,反之则不能。变量本身通过访问权限可以知道是否被序列,在此之外还可以使用[SerializeField] [NonSerialized] [Serializable] 这几个Attribute改变序列化与不被序列化。
- 被序列化的值也可以不在Inspector面板中显示,使用[HideInInspector]特性来隐藏。
- 不被序列化的值是不可以在Inspector面板中显示的。
自定义的inspector面板
CustomEditor
就是告诉编辑器要对该类所在的inspector面板进行操作
用法
//用于对LookAtPoint组件所在inspector面板进行扩展
[CustomEditor(typeof (LookAtPoint))]
OnInspectorGUI
用于实现扩展功能,比如说label,Toggle等功能,只能在该方法先实现
using UnityEditor;
public class EditorScritp : Editor {
public override void OnInspectorGUI()
{
GUILayout.Label("This is a Label in a Custom Editor");
}
}
上面完整代码
using UnityEditor;
//用于对LookAtPoint组件所在inspector面板进行扩展 LookAtPoint非Editor脚本,而是常用组件脚本
[CustomEditor(typeof (LookAtPoint))]
public class EditorScritp : Editor {
public override void OnInspectorGUI()
{
GUILayout.Label("This is a Label in a Custom Editor");
}
}
效果如下
CanEditMultipleObjects
用于选中多个物体在同一类型组件上修改
用法
和CustomEditor一样,放在类上面
没添加情况下
选择多个不会显示输入框
添加了情况下
属性
常用于显示在inspector面板的,平常只能定义一些常用属性,使用编辑器扩展可以定义多种样式,比如说:纹理,展示图片等
分成两个脚本,继承自MonoBehaviour用于定义属性,继承自Editor类用于定义显示样式
SerializedProperty/SerializedObject
SerializedProperty:用于对属性进行编辑
SerializedObject:对修改的属性进行刷新等操作
两者搭配使用
数组/List
PropertyField
通过PropertyField简单显示数组或者集合,通过EditorGUILayout访问
//继承自MonoBehaviour
[ExecuteInEditMode] //让脚本在编辑模式下也可以运行
public class LookAtPoint : MonoBehaviour {
//序列化
[SerializeField]
public int[] intArray;
[SerializeField]
public List<string> stringList;
}
//继承自Editor
[CustomEditor(typeof (LookAtPoint))]
public class EditorScritp: Editor
{
private SerializedProperty intArray;
private SerializedProperty stringList;
private void OnEnable()
{
//按照名称查找属性
intArray = serializedObject.FindProperty("intArray");
stringList = serializedObject.FindProperty("stringList");
}
public override void OnInspectorGUI()
{
//更新序列化的显示方式
serializedObject.Update();
//绘制样式
EditorGUILayout.PropertyField(intArray, true);
EditorGUILayout.PropertyField(stringList, true);
//对修改的属性进行应用
serializedObject.ApplyModifiedProperties();
}
}
效果如下
ReorderableList
实现可排序列表,可通过鼠标拖动,修改列表元素的排列顺序,注意其命名空间为UnityEditorInternal
由于其是内部使用,所以没有记录早Unity文档里
[ExecuteInEditMode] //让脚本在编辑模式下也可以运行
public class LookAtPoint : MonoBehaviour {
[SerializeField]
public List<string> stringArray;
}
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
[CanEditMultipleObjects]
[CustomEditor(typeof (LookAtPoint))]
public class EditorScritp: Editor
{
private SerializedProperty stringArray;
private ReorderableList _stringArray;
private void OnEnable()
{
//按照名称查找属性
stringArray = serializedObject.FindProperty("stringArray");
_stringArray = new ReorderableList(serializedObject, stringArray, true, true, true, true);
_stringArray.drawElementCallback = DrawNameElement;
}
//绘制元素 添加输入框
private void DrawNameElement(Rect rect, int index, bool selected, bool focused)
{
SerializedProperty itemData = _stringArray.serializedProperty.GetArrayElementAtIndex(index);
rect.y += 2;
rect.height = EditorGUIUtility.singleLineHeight;
EditorGUI.PropertyField(rect, itemData, GUIContent.none);
}
public override void OnInspectorGUI()
{
//更新序列化的显示方式
serializedObject.Update();
_stringArray.DoLayoutList();
//对修改的属性进行应用
serializedObject.ApplyModifiedProperties();
}
}
效果如下
就可以实现拖动效果了
详情可查看底部文章链接
变量
名称 | 描述 |
---|---|
draggable | 拖曳排序 |
displayAdd | 显示添加按钮 |
displayRemove | 显示移除按钮 |
elementHeight | 元素高度 |
headerHeight | 表头高度 |
footerHeight | 尾部高度 |
showDefaultBackground | 显示默认背景 |
公有方法
名称 | 描述 |
---|---|
DoLayoutList | 自动布局绘制列表 |
DoList(Rect rect) | 指定区域绘制列表 |
GetHeight | 获取绘制列表总高度 |
委托
名称 | 描述 |
---|---|
drawHeaderCallback | 绘制表头回调 |
drawFooterCallback | 绘制尾部回调 |
drawElementCallback | 绘制元素回调 |
drawElementBackgroundCallback | 绘制元素背景回调 |
onReorderCallback | 重新排序回调 |
onSelectCallback | 选中回调 |
onAddCallback | 添加按钮回调 |
onAddDropdownCallback | 添加下拉选项回调 |
onRemoveCallback | 移除元素回调 |
onMouseUpCallback | 鼠标抬起回调 |
onCanRemoveCallback | 是否显示可移除按钮回调 |
onChangedCallback | 列表改变回调 |
PropertyDrawer
绘制列表元素,在OnGUI方法下使用
参考官网
Gizmos
是Scene场景的可视化调试或辅助工具。脚本放在Gizmos文件夹下,继承于monobehaviour类,通过OnDrawGizmo或者OnDrawGizmosSelected实现
- OnDrawGizmo:用于每帧调用,使用相对场景视图鼠标的位置
- OnDrawGizmosSelected:脚本附加的对象被选中时才会被调用。例如:可以绘制一个显示爆炸半径的球体
//在一个空的Object上绘制Cube
//绘制效果一直显示
private void OnDrawGizmos()
{
var color = Gizmos.color;
Gizmos.color = Color.white;
Gizmos.DrawCube(transform.position, Vector3.one);
// Gizmos.color作为全局的静态变量,为了防止这里的color修改会对其他地方的绘制造成影响,所以在绘制完Gizmos的时候,将Gizmos.color修改为原先的值。
Gizmos.color = color;
}
//绘制效果在选中对象时显示
private void OnDrawGizmosSelected()
{
var color = Gizmos.color;
Gizmos.color = Color.white;
Gizmos.DrawWireCube(transform.position, Vector3.one);
// Gizmos.color作为全局的静态变量,为了防止这里的color修改会对其他地方的绘制造成影响,所以在绘制完Gizmos的时候,将Gizmos.color修改为原先的值。
Gizmos.color = color;
}
效果如下
特性
DrawGizmo,为任何组件使用Gizmo。是Editor下,
用法
放在方法上,满足条件则执行方法,方法为static
DrawGizmo(GizmoType gizmo, Type drawnGizmoType);
- 第一个参数:什么时候绘制
- 第二个参数:绘制的对象类型
[DrawGizmo(GizmoType.NotInSelectionHierarchy | GizmoType.Pickable)]
static void drawGizmo1(Light light, GizmoType gizmoType)
{
Vector3 position = light.transform.position;
Gizmos.DrawIcon(position + Vector3.up, "ninja.jpg");
}
什么时候绘制
GizmoType | 描述 |
---|---|
Active | 激活时,绘制 |
InSelectionHierarchy | 选中时或者其子节点被选中时,绘制 |
Selected | 选中时,绘制 |
NonSelected | 未选中时,绘制 |
NotInSelectionHierarchy | 未选中时或者其子节点未被选中时,绘制 |
Pickable | 在编辑器中选中时,绘制 |
常用方法
- Gizmos.DrawCube():绘制实体立方体
- Gizmos.DrawWireCube(): 绘制立方体边框
- Gizmos.DrawRay():绘制射线
- Gizmos.DrawLine():绘制直线
- Gizmos.DrawIcon():绘制Icon,Icon素材需要放在Gizmos文件夹中
- Gizmos.DrawFrustum():绘制摄像机视椎体的视野范围
Scene视图
为Scenes视图添加功能,命名空间是using UnityEditor; OnSceneGUI方法内编写, Handles绘制句柄
如果想要绘制GUI,则必须要在BeginGUI、EndGUI的方法对中
using UnityEditor;
using UnityEngine;
[CanEditMultipleObjects]
[CustomEditor(typeof (LookAtPoint))]
public class EditorScritp: Editor {
//获取SceneExt脚本对象
private LookAtPoint _target { get { return target as LookAtPoint; } }
private void OnSceneGUI()
{
//操作句柄
Handles.Label(_target.transform.position, _target.transform.name + " : " + _target.transform.position);
//绘制GUI的内容必须要在BeginGUI、EndGUI的方法对中
Handles.BeginGUI();
//设置GUI绘制的区域
GUILayout.BeginArea(new Rect(50, 50, 200, 200));
GUILayout.Label("Scene 扩展练习");
GUILayout.EndArea();
Handles.EndGUI();
}
}
效果如下
参考
- 官网-扩展编辑器
- ivy_0709-Unity编辑器扩展之Component的Inspector面板
- 庸人自扰Eam-Unity Editor 基础篇(二):自定义 Inspector 面板
- 虚拟喵-Unity 编辑器扩展总结 五:Gizmos辅助调试工具