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

Unity Scriptable Object中List使用问题求助:元素显示异常与数量限制失效

Unity Scriptable Object List 问题解决方案

我来帮你解决这两个Inspector面板的小问题,都是Unity默认编辑器行为导致的小坑,咱们一步步来处理:

问题1:第0个元素始终最小化

Unity默认的List绘制器在处理同时带有[TextArea]属性的List元素时,第一个元素的TextArea布局会出问题,导致它默认折叠成最小高度。解决这个问题的最佳方式是写一个自定义PropertyDrawer,手动控制每个List元素的TextArea显示:

  1. 在你的项目中创建一个新的Editor脚本(比如命名为TextAreaListDrawer.cs),放在Editor文件夹下(如果没有就新建一个):
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;

[CustomPropertyDrawer(typeof(List<string>), true)]
public class TextAreaListDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginProperty(position, label, property);

        // 绘制List的标题和折叠箭头
        property.isExpanded = EditorGUI.Foldout(new Rect(position.x, position.y, position.width, 16), property.isExpanded, label);

        if (property.isExpanded)
        {
            EditorGUI.indentLevel++;

            // 获取List的大小
            SerializedProperty sizeProp = property.FindPropertyRelative("Array.size");
            EditorGUI.PropertyField(new Rect(position.x, position.y + 18, position.width, 16), sizeProp);

            // 遍历每个元素,用TextArea绘制
            for (int i = 0; i < sizeProp.intValue; i++)
            {
                SerializedProperty elementProp = property.GetArrayElementAtIndex(i);
                Rect elementRect = new Rect(position.x, position.y + 18 * (i + 2), position.width, 40); // 固定40高度,可按需调整
                elementProp.stringValue = EditorGUI.TextArea(elementRect, elementProp.stringValue);
            }

            EditorGUI.indentLevel--;
        }

        EditorGUI.EndProperty();
    }

    // 重写高度计算,确保足够显示所有元素
    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        if (!property.isExpanded)
        {
            return 16; // 折叠状态下的高度
        }

        SerializedProperty sizeProp = property.FindPropertyRelative("Array.size");
        return 16 + 18 + (sizeProp.intValue * 40); // 标题+大小字段+每个元素40高度
    }
}

这个Drawer会强制每个List元素都以固定高度的TextArea显示,第一个元素就不会再默认最小化了。

问题2:Range属性无法限制List长度

[Range(1,5)]是用来限制单个数值字段范围的,对List的元素数量完全不起作用——这是属性的设计逻辑问题。要限制List最多5个元素,有两种简单的解决方法:

方法1:用OnValidate自动截断(简单快捷)

在你的Scriptable Object类中添加OnValidate()方法,每次Inspector里的数值变化时自动检查并截断List:

using UnityEngine;
using System.Collections.Generic;

[CreateAssetMenu(fileName = "NewMCQ", menuName = "MCQ/Question")]
public class MCQQuestion : ScriptableObject
{
    [SerializeField] [TextArea(1,2)] List<string> answerList = new List<string>();

    void OnValidate()
    {
        if (answerList == null)
        {
            answerList = new List<string>();
            return;
        }

        // 限制最多5个元素,超过就截断
        if (answerList.Count > 5)
        {
            answerList.RemoveRange(5, answerList.Count - 5);
            Debug.LogWarning($"[{name}] Answer list can't have more than 5 elements. Truncated to 5.");
        }

        // 可选:限制最少1个元素,对应Range的最小值
        if (answerList.Count < 1)
        {
            answerList.Add("");
            Debug.LogWarning($"[{name}] Answer list must have at least 1 element. Added empty entry.");
        }
    }
}

这样用户即使手动添加超过5个元素,Unity也会自动把多余的删掉,还会给出警告提示。

方法2:自定义Drawer阻止添加(更友好的交互)

如果想让用户根本无法添加超过5个元素,可以修改刚才的TextAreaListDrawer,在List大小达到5时隐藏添加按钮:
在Drawer的OnGUI方法里,绘制sizeProp的时候加个判断:

// 绘制List的大小,当数量达到5时禁用输入
if (sizeProp.intValue >= 5)
{
    EditorGUI.BeginDisabledGroup(true);
    EditorGUI.PropertyField(new Rect(position.x, position.y + 18, position.width, 16), sizeProp);
    EditorGUI.EndDisabledGroup();
    // 额外加个提示文本
    EditorGUI.LabelField(new Rect(position.x, position.y + 36, position.width, 16), "Max 5 answers allowed", EditorStyles.miniLabel);
}
else
{
    EditorGUI.PropertyField(new Rect(position.x, position.y + 18, position.width, 16), sizeProp);
}

这样用户就不能把List大小调到5以上,从根源上阻止了多余元素的创建。

最终建议

如果追求快速解决,用**方法1(OnValidate)**就足够了;如果想要更流畅的Inspector体验,就结合自定义Drawer同时解决两个问题。记得把自定义Drawer脚本放在Editor文件夹下,否则打包的时候会报错哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:34:10