自定义脚本界面有两种方法,一种是继承PropertyDrawer,一种是继承editor
下面介绍继承自PropertyDrawer
PropertyDrawer有两种用途,一种是自定义绘制带有Serializable属性的类,一种是自定义继承自PropertyAttribute的类
1.绘制带有Serializable属性的类在重新绘制该类的时候,绘制类要继承自PropertyDrawer,且加上CustomPropertyDrawer属性
using System;
using UnityEngine;
public enum IngredientUnit { Spoon, Cup, Bowl, Piece }
// 自定义绘制类,没有继承mono
[Serializable]
public class Ingredient
{
public string name;
public int amount = 1;
public IngredientUnit unit;
}
//继承mono,默认绘制
public class Recipe : MonoBehaviour
{
public Ingredient potionResult;
public Ingredient[] potionIngredients;
}
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
// IngredientDrawerUIE
[CustomPropertyDrawer(typeof(Ingredient))]
public class IngredientDrawerUIE : PropertyDrawer
{
public override VisualElement CreatePropertyGUI(SerializedProperty property)
{
// Create property container element.
var container = new VisualElement();
// Create property fields.
var amountField = new PropertyField(property.FindPropertyRelative("amount"));
var unitField = new PropertyField(property.FindPropertyRelative("unit"));
var nameField = new PropertyField(property.FindPropertyRelative("name"), "Fancy Name");
// Add fields to the container.
container.Add(amountField);
container.Add(unitField);
container.Add(nameField);
return container;
}
}
2.绘制继承自PropertyAttribute类的属性
比如系统自带的属性 Range
下面我们自己实现一个和Range属性一样的属性
using UnityEngine;
public class RangeAttribute : PropertyAttribute
{
public float min;
public float max;
public RangeAttribute(float min, float max)
{
this.min = min;
this.max = max;
}
}
[CustomPropertyDrawer(typeof(RangeAttribute))]
public class RangeDrawer : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// First get the attribute since it contains the range for the slider
RangeAttribute range = attribute as RangeAttribute;
// Now draw the property as a Slider or an IntSlider based on whether it's a float or integer.
if (property.propertyType == SerializedPropertyType.Float)
EditorGUI.Slider(position, property, range.min, range.max, label);
else if (property.propertyType == SerializedPropertyType.Integer)
EditorGUI.IntSlider(position, property, Convert.ToInt32(range.min), Convert.ToInt32(range.max), label);
else
EditorGUI.LabelField(position, label.text, "Use Range with float or int.");
}
}