Unity-检查器中结构的自定义绘图

y

我有一个自定义结构,具有以下代码:

[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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Unity-基于结构文件的检查器中的自定义结构名称

在Unity自定义检查器中设置枚举控件

Unity自定义检查器,允许选择的子对象

使用自定义检查器扩展Unity UI组件

Unity:ScriptableObject的自定义检查器不起作用

是否可以在Unity的自定义检查器中显示Partial枚举?

Unity中的自定义编辑器继承

如何创建可折叠的汉堡菜单图标自定义检查器/编辑器Unity

如何在Unity中使自定义检查器添加对象引用

Unity3D 自定义检查器未正确保存值

Unity-使用自定义检查器时可以访问OnValidate()吗?

无法在Unity中的自定义着色器中设置动画或更改颜色?

Unity - 自定义编辑器 - 数据刷新

Unity自定义编辑器GUI

在Unity中自动添加脚本自定义编辑器的快捷方式

Unity在自定义编辑器面板中动态限制滑块

开始游戏时,Unity3D值从自定义编辑器中消失

Unity中的自定义日期和时间

从Unity 4.x升级后,Unity 5自定义着色器损坏

Unity vs自定义依赖注入?

创建自定义Unity Inspector布局

自定义形状按钮 Unity UI

Unity-如何创建自定义编辑器以动态更改另一个具有自定义大小的列表中列表的大小?

在Unity Webplayer中与自定义朋友发送请求时,Facebook Unity SDK出现错误

创建自定义地形编辑器(Unity C#)时出错

使用Unity启动器图标加入自定义终端快捷方式

具有动态枚举字段的自定义Unity C#脚本编辑器

Unity:如何将未知脚本动态附加到GameObject(自定义编辑器)

创建类似Game Creator的工具| Unity编辑器自定义