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

Unity自定义PropertyDrawer滚动触发System.ArgumentException问题求助

解决Inspector滚动时自定义PropertyDrawer的ArgumentException错误

核心问题定位

这个错误通常是因为滚动时被遮挡字段的序列化对象引用失效,或是绘制属性时未正确处理SerializedProperty的有效性、可见性状态。比如对象移出视口后,Unity可能临时释放部分序列化数据引用,此时直接访问property.objectReferenceValue或其属性就会触发参数异常。

具体修复步骤

1. 严格校验SerializedProperty及引用对象有效性

在OnGUI方法开头就做有效性检查,避免无效访问:

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
    // 校验核心对象有效性
    if (property == null || property.propertyType != SerializedPropertyType.ObjectReference)
    {
        EditorGUI.LabelField(position, label, new GUIContent("Invalid object reference field"));
        return;
    }

    var targetObj = property.objectReferenceValue;
    if (targetObj == null)
    {
        EditorGUI.ObjectField(position, property, label);
        return;
    }

    // 后续绘制逻辑放在此处
}

2. 使用SerializedObject处理目标对象属性

不要直接通过反射访问目标对象属性,而是将其包装成SerializedObject,借助Unity序列化系统处理绘制,避免状态不一致:

// 替换直接反射的逻辑
var serializedTarget = new SerializedObject(targetObj);
serializedTarget.Update();

// 获取Attribute指定的要显示的属性
var displayProps = attribute as DisplayPropertiesAttribute;
foreach (var propName in displayProps.PropertyNames)
{
    var childProp = serializedTarget.FindProperty(propName);
    if (childProp != null)
    {
        position.height = EditorGUI.GetPropertyHeight(childProp);
        EditorGUI.PropertyField(position, childProp);
        position.y += position.height + EditorGUIUtility.standardVerticalSpacing;
    }
}

serializedTarget.ApplyModifiedProperties();

3. 用BeginProperty/EndProperty维护字段状态

Unity滚动时依赖这对方法维护字段状态,必须包裹整个绘制逻辑:

public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
    EditorGUI.BeginProperty(position, label, property);

    // 上述校验与绘制逻辑放在此处

    EditorGUI.EndProperty();
}

4. 重写GetPropertyHeight时也要做有效性校验

自定义高度计算时,同样要检查对象有效性,避免返回错误高度导致布局混乱:

public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
    if (property == null || property.objectReferenceValue == null)
    {
        return EditorGUI.GetPropertyHeight(property, label);
    }

    var serializedTarget = new SerializedObject(property.objectReferenceValue);
    var displayProps = attribute as DisplayPropertiesAttribute;
    float totalHeight = EditorGUI.GetPropertyHeight(property, label) + EditorGUIUtility.standardVerticalSpacing;

    foreach (var propName in displayProps.PropertyNames)
    {
        var childProp = serializedTarget.FindProperty(propName);
        if (childProp != null)
        {
            totalHeight += EditorGUI.GetPropertyHeight(childProp) + EditorGUIUtility.standardVerticalSpacing;
        }
    }

    return totalHeight - EditorGUIUtility.standardVerticalSpacing; // 移除最后一个多余间距
}

数组显示问题临时处理(可选)

如果数组显示异常,确保用EditorGUI.PropertyField绘制数组元素,并分配正确的Rect区域:

// 数组属性绘制示例
if (childProp.isArray)
{
    position.height = EditorGUI.GetPropertyHeight(childProp);
    EditorGUI.PropertyField(position, childProp, true); // 第二个参数true表示展开数组
    position.y += position.height + EditorGUIUtility.standardVerticalSpacing;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 02:05:12