通过内置特性扩展编辑器

Unity 也提供了大量用以扩展编辑器的内置特性。

内置 GUIStyle 样式

Unity 内置有很多固定样式,定义在 GUI.skin.customStyles 中。以下代码生成一个简单的窗口以列举这些样式:

using UnityEngine;
using UnityEditor;

namespace InspectorExtension.GUIStyleTools {
		public class BuiltInStyles : EditorWindow {
				Vector2 _scroll = Vector2.zero;
		
				[MenuItem("Tools/Built In Styles/Display")]
				static void Display () {
						GetWindow (typeof (BuiltInStyles));
				}
		
				void OnGUI () {
						_scroll = EditorGUILayout.BeginScrollView (_scroll);
			
						foreach (GUIStyle style in GUI.skin.customStyles) {
								GUIContent content = new GUIContent (style.name);
								float minWidth = 0, maxWidth = 0;
								float minHeight = 0, maxHeight = 0;
				
								style.CalcMinMaxWidth (content, out minWidth, out maxWidth);
								minHeight = style.CalcHeight (content, minWidth);
								maxHeight = style.CalcHeight (content, maxWidth);
				
								EditorGUILayout.BeginHorizontal ("box", GUILayout.Height(maxHeight));
				
								// style name
								EditorGUILayout.SelectableLabel (style.name, GUIStyle.none, GUILayout.Width(100));
								EditorGUILayout.Space ();
				
								// style content
								EditorGUILayout.SelectableLabel (style.name, style);
				
								EditorGUILayout.EndHorizontal ();
						}
			
						EditorGUILayout.EndScrollView ();
				}
		}
}

点击菜单栏中的 Tools/Built In Styles/Display 后生成的窗口如下:

部分 GUI 元素不适合用于带有内容的情况(例如窗口的最小化按钮),所以存在拉伸或扭曲的现象。

属性绘制器 Property Drawers

Unity 内置有很多属性绘制器用以扩展编辑器,一般以 Attribute 的形式添加在相应的属性代码上方。

内置属性绘制器

说明使用方法
限制整型或浮点型变量在某个特定范围内RangeAttribute(int min, int max) , RangeAttribute(float min, float max)
使字符串以多行的形式显示,可以设定具体显示多少行MultilineAttribute() , MultilineAttribute(int lines)
以 TextArea 的形式显示字符串,可以设定最多显示的行、列数TextAreaAttribute() , TextAreaAttribute(int minLines, int maxLines)
使某个特定方法可以在组件或脚本的上下文菜单中访问ContextMenuAttribute(string name)
使某个特定的非静态方法可以在属性的上下文菜单中访问ContextMenuItemAttribute(string name, string function)

以下代码是上述绘制器的实例:

using UnityEngine;

public class PropertyDrawers : MonoBehaviour {
		[Range (-5, 5)]
		public int _int = -2;
	
		[Range (-5.0f, 5.0f)]
		public float _float = 3.14f;
	
		[Multiline ()]
		[ContextMenuItem ("Add Line To All", "AddLine")]
		public string _text = "Line 1\nLine 2";
	
		[Multiline (2)]
		[ContextMenuItem ("Add Line To All", "AddLine")]
		public string _text_2 = "Line 1\nLine 2";
	
		[TextArea ()]
		[ContextMenuItem ("Add Line To All", "AddLine")]
		public string _textArea = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7";
	
		[TextArea (4, 6)]
		[ContextMenuItem ("Add Line To All", "AddLine")]
		public string _textArea_4_6 = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7";
	
		[ContextMenu("Reset All Value")]
		public void ResetAll () {
				_int = -2;
		 		_float = 3.14f;
		 		_text = "Line 1\nLine 2";
		 		_text_2 = "Line 1\nLine 2";
		 		_textArea = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7";
		 		_textArea_4_6 = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7";
		}
	
		public void AddLine() {
				_text += "\nNew Line";
				_text_2 += "\nNew Line";
				_textArea += "\nNew Line";
				_textArea_4_6 += "\nNew Line";
		}
}

生成的 Inspector 面板如下:

装饰绘制器 Decorator Drawers

Unity 中有另一种绘制器——装饰绘制器,用法与属性绘制器十分类似,不同在于,设计装饰绘制器的目的是装饰 inspector 面板,并不和某一特定域联系(但仍需要放置在某个域的上方);每个变量上仅可以声明一个同类型的属性绘制器,而装饰绘制器可以声明多个;另外,当声明在数组或者列表上方时,属性绘制器会作用于结构中的每一个元素,但装饰绘制器只会在最开始绘制一次。

内置装饰绘制器

说明使用方法
添加标题HeaderAttribute(string header)
添加空白SpaceAttribute(float height)
添加提示TooltipAttribute(string tooltip)
using UnityEngine;

public class DecoratorDrawers : MonoBehaviour {
		[Header ("Int Values")]
		[Space (10)]
		[Tooltip ("This is an int value.")]
		public int _int_1;
		[Space (10)]
		public int _int_2;
		[Space (10)]
		public int _int_3;
	
		[Header ("Float Values")]
		[Range (-5f, 5f)]
		[Space (20)]
		public float [] _floats = new float [3];
}

生成的 Inspector 面板如下: