我有以下不可变结构体。
[Serializable]
public readonly struct Wind
{
/// <param name="windSpeed">The speed of the wind</param>
/// <param name="rho">The density of the air, if not provided 15 degrees assumed aka 1.225f</param>
public Wind(Vector3 windSpeed, float rho = 1.225f)
{
Speed = windSpeed;
Rho = rho;
}
/// <summary>
/// The speed of the wind [m/s]
/// </summary>
[DisplayReadOnly]
public readonly Vector3 Speed;
/// <summary>
/// Density of the air [kg/m^3]
/// </summary>
[DisplayReadOnly]
public readonly float Rho;
}
这样做的问题在于,Unity无法序列化只读字段,所以我按照Anton Semchenko的指导创建了一个属性,在检视面板中仅显示这些字段以方便调试。
以下是我创建的脚本:
自定义属性绘制器
[CustomPropertyDrawer(typeof(DisplayReadOnlyAttribute))]
public class DisplayReadOnlyAttributeDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
DisplayReadOnlyAttribute att = (DisplayReadOnlyAttribute)attribute;
object obj = property.serializedObject.targetObject;
Type type = obj.GetType();
FieldInfo field = type.GetField(property.propertyPath, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
object val = field?.GetValue(obj);
if (att.warningIfNull && (val == null || val.ToString().Equals("null")))
val += " <-This value should NOT be NULL!";
EditorGUI.LabelField(position, string.Format("{0}: {1}", label.text, val));
}
}
显示只读属性在检查器中的属性信号。
public class DisplayReadOnlyAttribute : PropertyAttribute
{
/// <summary>
/// Writes a warning if the value of this field is null
/// </summary>
public readonly bool warningIfNull = false;
public DisplayReadOnlyAttribute(bool _warningIfNull = false)
{
warningIfNull = _warningIfNull;
}
}
问题在于,如果将此属性应用于只读字段,它将不起作用。它仅在应用于非只读字段时才被调用。 public float Rho;
我不仅对上述解决方案感兴趣,如果您知道以另一种方式显示只读字段,请不要独自保留。