官方文档 PropertyDrawers
Unity编辑器拓展(一)
Unity编辑器拓展(二)
Unity编辑器拓展(三)
绘制属性 Property Drawers
绘制属性可用于脚本上的属性,在 Inspector 窗口中自定义某些控件的外观,或者控制特定的可序列化类的外观。
绘制属性有两种用途:1.为可序列化类的每个实例自定义 GUI。2.为脚本成员属性自定义 GUI。
为可序列化类的每个实例自定义 GUI
如果脚本中属性是自定义类,在 Inspector 中是不会显示的,如果需要显示,我们可用 Serializable 修饰。
示例1:
using System; // for Serializable
public enum IngredientUnit { Spoon, Cup, Bowl, Piece }
[Serializable]
public class Ingredient {
public string name;
public int amount = 1;
public IngredientUnit unit;
}
public class GameRecipe : MonoBehaviour {
public Ingredient potionResult;
public Ingredient[] potionIngredients;
}
正确显示如下图所示:
我们可以使用 CustomPropertyDrawer 来自定义我们需要的显示效果。如示例2:
[CustomPropertyDrawer(typeof(Ingredient))]
public class IngredientDrawer : PropertyDrawer {
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
EditorGUI.BeginProperty(position, label, property); // 开始绘制属性
var indent = EditorGUI.indentLevel; // 用来缓存修改之前的缩进值
EditorGUI.indentLevel = 0; // 修改缩进为 0,不缩进
// 获取属性前值 label, 就是显示在此属性前面的那个名称 label
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
// 定义此属性的子框体区域
var amountRect = new Rect(position.x, position.y, 30, position.height);
var unitRect = new Rect(position.x + 35, position.y, 50, position.height);
var nameRect = new Rect(position.x + 90, position.y, position.width - 90, position.height);
// 绘制子属性:PropertyField参数依次是: 框体位置,对应属性,显示的label
// 如果你要显示一个label,第三个参数: new GUIContent("xxx")
EditorGUI.PropertyField(amountRect, property.FindPropertyRelative("amount"), GUIContent.none);
EditorGUI.PropertyField(unitRect, property.FindPropertyRelative("unit"), GUIContent.none);
EditorGUI.PropertyField(nameRect, property.FindPropertyRelative("name"), GUIContent.none);
EditorGUI.indentLevel = indent; // 恢复缩进
EditorGUI.EndProperty(); // 完成绘制
}
}
显示效果图:
为脚本成员属性自定义 GUI
使用 Property Attributes 来给脚本的成员属性自定义GUI。你可以使用内建的和自定义的。
内建属性有:
- Range() 将一个值指定在一定的范围内,在Inspector面板中为其添加滑块
- Multiline() 为一个string指定多行
- Header() 为属性添加属性标题
- Tooltip() 为属性添加提示语
- Space() 添加指定行距
- ContextMenu() 为脚本添加菜单到右上角工具按钮
- TextArea() 添加TextArea
示例3:
public class GameRecipe : MonoBehaviour {
public Ingredient potionResult;
public Ingredient[] potionIngredients;
[Header("Nick")]
public string nickName;
[Multiline(3)]
public string description;
[Space(20)]
[Range(0f, 10f), Tooltip("this is weight")]
public float weight;
[TextArea]
public string information;
[ContextMenu("Show Infomation")]
void ShowInfo() {
Debug.Log(information);
}
}
效果如图:
自定义 PropertyAttribute:1.派生 PropertyAttribute 并定义此类。2. 在使用 CustomPropertyDrawer 实现绘制。
这种实现和之前的示例2类似就不展示示例了。