我有一个自定义结构,具有以下代码:
[Serializable]
public struct HexPoint : IEquatable<HexPoint>
{
public readonly int x;
public readonly int y;
public readonly int z;
// Some custom methods for initializations and operators
}
如果我将x,y和z变量设为非只读,则它们会很好地显示在统一检查器中。但是,我有一些他们需要满足的规则(实际上x + y + z = 0),因此我添加了只读权限,以防止人们惹它。
但是作为只读变量,它们不会显示(因为它们不能被修改)!:(
我想知道它们是否是我可以在统一检查器中显示它们的一种方式,类似于PropertyDrawer。我知道我可以将结构切换到类,因为PropertyDrawer是为类保留的,但是我想将其保留为结构。
因此,有没有一种显示值的方法?最终使用自定义初始化程序修改它们?
非常感谢 !
readonly
使它们也non-serialized
->不显示在检查器中
注意这PropertyDrawer
是不局限于class
类型,但也可以使用struct
的类型。
实际上没有必要CustomPropertyDrawer
。
您可以具有公共只读属性,以访问私有字段并在Inspector使用中显示它们,[SerializeField]
这使得它们只能通过Inspector进行编辑,而不能通过其他类进行编辑。
[Serializable]
public struct HexPoint : IEquatable<HexPoint>
{
// Those are not displayed in the inspector,
// readonly and accessible by other classes
public int x { get { return _x; } }
public int y { get { return _y; } }
public int z { get { return _z; } }
// if you prefer you can also use the expression body style instead
//public int x => _x;
//public int y => _y;
//public int z => _z;
// Those are displayed and editable in the Inspector
// but private and therefor not changeable by other classes
[SerializeField] private int _x;
[SerializeField] private int _y;
[SerializeField] private int _z;
public bool Equals(HexPoint other)
{
return _x == other._x && _y == other._y && _z == other._z;
}
public override bool Equals(object obj)
{
return obj is HexPoint other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = _x;
hashCode = (hashCode * 397) ^ _y;
hashCode = (hashCode * 397) ^ _z;
return hashCode;
}
}
}
如果您确实想使用aPropertyDrawer
来另外也不允许在Inspector中编辑这些值,但是仍然保存并看到它们,则可以添加一个,例如
[Serializable]
public struct HexPoint : IEquatable<HexPoint>
{
// Those are not displayed in the inspector,
// readonly and accessible by other classes
public int x { get { return _x; } }
public int y { get { return _y; } }
public int z { get { return _z; } }
// if you prefer you can also use the expression body style instead
//public int x => _x;
//public int y => _y;
//public int z => _z;
// Those are displayed and editable in the Inspector
// but private and therefor not changeable by other classes
[SerializeField] private int _x;
[SerializeField] private int _y;
[SerializeField] private int _z;
public bool Equals(HexPoint other)
{
return _x == other._x && _y == other._y && _z == other._z;
}
public override bool Equals(object obj)
{
return obj is HexPoint other && Equals(other);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = _x;
hashCode = (hashCode * 397) ^ _y;
hashCode = (hashCode * 397) ^ _z;
return hashCode;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(HexPoint))]
public class HexPointDrawer : PropertyDrawer
{
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
return EditorGUIUtility.singleLineHeight * (EditorGUIUtility.wideMode ? 1 : 2);
}
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
// Find the SerializedProperties by name
var x = property.FindPropertyRelative(nameof(_x));
var y = property.FindPropertyRelative(nameof(_y));
var z = property.FindPropertyRelative(nameof(_z));
// Using BeginProperty / EndProperty on the parent property means that
// prefab override logic works on the entire property.
EditorGUI.BeginProperty(position, label, property);
{
// Makes the fields disabled / grayed out
EditorGUI.BeginDisabledGroup(true);
{
// In your case the best option would be a Vector3Field which handles the correct drawing
EditorGUI.Vector3IntField(position, label, new Vector3Int(x.intValue, y.intValue, z.intValue));
}
EditorGUI.EndDisabledGroup();
}
EditorGUI.EndProperty();
}
}
#endif
}
更改后检查值的提示MonoBehaviour.OnValidate可能对您很有意义
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句