You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何无法在Mono脚本中访问PropertyDrawer创建的GapRangeDrawer属性?

解决Unity自定义Range属性无法访问的问题

问题根源

你混淆了**自定义特性(Attribute)和属性抽屉(PropertyDrawer)**的作用:GapRangeDrawer是负责绘制Inspector UI的抽屉类,不能直接作为特性标注在字段上,必须先定义一个对应的自定义特性,再让抽屉类关联这个特性。

修复步骤

1. 创建自定义特性类

在Assets根目录下(不要放在Editor文件夹)新建脚本GapRangeAttribute.cs,代码如下:

using UnityEngine;

public class GapRangeAttribute : PropertyAttribute
{
    public float MinRange { get; private set; }
    public float MaxRange { get; private set; }
    public float Sensitivity { get; private set; }

    public GapRangeAttribute(float minRange, float maxRange, float sensitivity = 0.1f)
    {
        MinRange = minRange;
        MaxRange = maxRange;
        Sensitivity = sensitivity;
    }
}

2. 修改属性抽屉类

更新Assets/Editor/GapRangeDrawer.cs的代码,让它关联上面的特性,并从特性中获取参数:

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(GapRangeAttribute))] // 关联自定义特性
public class GapRangeDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // 获取关联的特性参数
        var gapRangeAttribute = attribute as GapRangeAttribute;

        if (property.propertyType == SerializedPropertyType.Float)
        {
            EditorGUI.BeginProperty(position, label, property);
            EditorGUI.Slider(position, property, gapRangeAttribute.MinRange, gapRangeAttribute.MaxRange, label);
            property.floatValue = RoundValue(property.floatValue, gapRangeAttribute.Sensitivity);
            EditorGUI.EndProperty();
        }
        else
        {
            EditorGUI.LabelField(position, label.text, "Use [GapRange] with float values only!");
        }
    }

    private float RoundValue(float value, float sensitivity)
    {
        return Mathf.Round(value / sensitivity) * sensitivity;
    }
}

注意:移除了原来的构造函数,因为PropertyDrawer的参数是通过关联的Attribute传递的,不需要自定义构造。

3. 在Mono脚本中正确使用

现在可以在CubeSpawner里正常使用自定义特性了:

public class CubeSpawner : MonoBehaviour
{
    public GameObject cubePrefab;
    [GapRange(0f, 10f, 0.5f)] // 最小值0,最大值10,步长0.5
    public float spawnGap;
}

额外说明

  • 自定义特性类必须放在非Editor目录,这样运行时和编辑时的脚本都能访问到。
  • PropertyDrawer类必须放在Assets/Editor目录下,Unity会自动识别并应用它的绘制逻辑。

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:45:14