Unity 2021.3.xf系列编辑器中序列化列表首个条目折叠异常问题求助
关于Unity 2021.3.x序列化列表折叠异常的解决方案
这个问题确实是Unity在2021.3系列版本中引入的Inspector序列化UI已知bug,我之前也碰到过类似情况,下面给你梳理下修复方向和临时解决办法:
一、已修复该问题的Unity版本
根据Unity官方版本更新日志,以下版本已经修复了列表/数组第一个条目折叠时渗透到后续元素的异常:
- 2021.3.18f1 及更高的2021.3.x补丁版本
- 2022.1.10f1 及更高的2022.1.x版本
- 2022.2.0b8 及更高的2022.2.x测试版
如果项目允许升级,优先建议切换到上述稳定版本,这是最彻底的解决方式。
二、未升级前的临时解决方案
如果暂时没法升级Unity版本,可以尝试以下几种方法:
1. 完善序列化标记
确保你的列表/数组及元素类型都正确配置了序列化属性:
- 非public的列表/数组字段必须标记
[SerializeField] - 自定义元素类要加上
[System.Serializable],保证Unity能正确识别其序列化结构 - 可以给列表字段添加
[InspectorName("自定义列表名称")],帮助Inspector更清晰地识别字段边界
2. 用自定义PropertyDrawer隔离折叠状态
默认Inspector渲染逻辑可能存在状态共享问题,你可以写一个简单的自定义PropertyDrawer,给每个列表项单独维护折叠状态:
using UnityEditor; using UnityEngine; [CustomPropertyDrawer(typeof(你的自定义攻击元素类))] public class AttackItemDrawer : PropertyDrawer { private bool _isExpanded = true; public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { // 绘制折叠按钮 _isExpanded = EditorGUI.Foldout(new Rect(position.x, position.y, position.width, 16), _isExpanded, label); if (_isExpanded) { EditorGUI.indentLevel++; // 依次绘制元素的各个属性 EditorGUI.PropertyField(new Rect(position.x, position.y + 18, position.width, 16), property.FindPropertyRelative("攻击名称")); EditorGUI.PropertyField(new Rect(position.x, position.y + 36, position.width, 16), property.FindPropertyRelative("攻击伤害")); EditorGUI.indentLevel--; } } public override float GetPropertyHeight(SerializedProperty property, GUIContent label) { // 根据折叠状态返回高度 return _isExpanded ? 16 * 3 : 16; } }
这个方案通过给每个列表项单独存储折叠状态,从根源上避免了第一个项的状态影响后续元素。
3. 临时规避方案
可以在列表的第一个位置添加一个空的占位元素(后续可删除),或者调整列表元素顺序,让第一个元素不是需要折叠的项,也能暂时绕过这个bug。
三、额外排查点
如果项目里有自定义Editor代码,要检查是否用了静态变量来存储折叠状态——静态变量会在所有列表项间共享,这也会导致类似的渗透问题,把静态变量改成非静态即可解决。
内容的提问来源于stack exchange,提问作者frad1582




