Unity Inspector结构体数组字段重叠、遮挡其他组件如何修复
问题表现

故障触发环境与特征:
- 出现在Unity 2021.3.3f1 LTS版本中
- 自定义可序列化结构体
SpawnableObject在Inspector中以数组形式展示时触发UI异常,单个结构体实例展示完全正常 - 重启Unity无法消除故障
- 异常仅作用于数组的第0号元素,其余元素可正常交互
关联代码
出问题的SpawnableObject结构体定义如下:
[Serializable] private struct SpawnableObject { public SpawnableObject(GameObject entity, float lowEndChance, float highEndChance) { chanceRange = new float[2]; if(lowEndChance > highEndChance) { float placeholder; placeholder = lowEndChance; lowEndChance = highEndChance; highEndChance = placeholder; Debug.LogWarning("lowEndChance is greater than highEndChance, swapping values."); } else if(lowEndChance == highEndChance) { highEndChance += 0.01f; Debug.LogWarning("lowEndChance equals highEndChance"); } this.entity = entity; isDefault = false; chanceRange[0] = lowEndChance; chanceRange[1] = highEndChance; } public SpawnableObject(GameObject entity, float lowEndChance, float highEndChance, bool isDefault) { chanceRange = new float[2]; if(lowEndChance > highEndChance) { float placeholder; placeholder = lowEndChance; lowEndChance = highEndChance; highEndChance = placeholder; Debug.LogWarning("lowEndChance is greater than highEndChance, swapping values."); } else if(lowEndChance == highEndChance) Debug.LogWarning("lowEndChance equals highEndChance"); this.entity = entity; this.isDefault = isDefault; chanceRange[0] = lowEndChance; chanceRange[1] = highEndChance; } [SerializeField] public GameObject entity; [SerializeField] public float[] chanceRange; [SerializeField] public bool isDefault; }
临时规避方案
不需要改代码的临时操作方法,可暂时保证编辑器正常使用:
- 点击挂载对应脚本/组件右上角的三个点按钮,选择「Properties...」选项,弹出的属性菜单内UI可正常交互
- 由于异常仅影响数组第0号元素,可暂时跳过该元素,从第1号元素开始完成配置操作
永久修复方案
故障本质是Unity 2021.3版本值类型(struct)数组序列化的已知bug:当struct内部包含数组类型的引用成员,且该成员未在字段声明阶段初始化时,数组第0位的序列化数据会和外层结构体数组的第0位数据发生内存布局冲突,导致Inspector渲染崩溃。
修复步骤:
- 修改
chanceRange字段的声明,直接在字段定义时初始化固定长度的数组,替换原有声明:
// 原代码 // [SerializeField] public float[] chanceRange; // 修改为 [SerializeField] public float[] chanceRange = new float[2];
- 删除两个构造函数中重复初始化
chanceRange的代码行chanceRange = new float[2];,避免覆盖序列化时的已有值。 - 回到编辑器等待脚本编译完成后,右键对应组件选择「Reset」清空旧的异常序列化数据,重新配置参数即可恢复正常。
如果不想修改结构体初始化逻辑,也可以直接将SpawnableObject从struct改为class,引用类型的序列化不会触发该值类型专属bug,但会改变类型的传参语义,可根据实际需求选择。
内容的提问来源于stack exchange,提问作者VeryBadProgrammer
相关产品推荐
相关产品推荐

