如果文章对你有用,点个赞吧!
场景:在某一帧里删除了具有组件Vertical LayOut Group 或 Horizontal LayOut Group的物体的子物体,然后将该父物体的active设为false,下一帧启动它(并尝试添加新的子物体)时报错
原理:LayOutGroup的刷新需要一帧的时间,并且是OnUpdate之后(猜测是在OnRender或者OnGizmos)的位置来绘制新的可能的子物体排序。
假如在修改子物体后将父物体设为false,由于父物体失活,不会执行LayoutGroup的更新,导致此时Layout仍然以为它拥有被删除的子物体,下次被激活时尝试调用并排序它们,由于它们已经被删除,指向为空,导致报空错。
实例:对于父物体A,下挂子物体B C D,在帧数1中删除B C D并设A为false,此时A的layoutGroup由于没有更新,仍然认为B C D存在(实际上A下挂的BCD已经被删除了),只是此时不作报错。
当某一帧父物体A再次被激活,会首先尝试排序B C D以及可能的新子物体,此时指向B C D的指针为空(意会),导致报错"RectTransform" has been destroyed but you are still trying to access it.
解决方案:
当挂有LayoutGroup的物体在某一帧中同时执行 删除子物体 - 失活父物体动作时,于中间插入强制刷新代码,即:删除子物体 - 强制刷新 - 失活父物体(貌似不正确)
此处有效的解决方案是:在帧数1中删除子物体 - 失活父物体,帧数2中 强制刷新 -添加新的子物体
如果在同一函数中执行所有4个操作仍然会导致报错,但可以正常生成和排序子物体,原理不明。
LayoutRebuilder.ForceRebuildLayoutImmediate(tagParent.GetComponent<RectTransform>());
2024.5.18
第一次编辑:
尝试了几个方案,仍然无法做到在同一个函数中进行 物体删除 - 物体生成 时不报错,即使插入大量强制刷新函数也不行,期待大手子分享具体原理和解决方案
目前只能用一个性能非常差的替代方案来解决功能实现问题:每次失活时删除所有子物体,下一帧开始时强制刷新LayoutGroup,然后根据输入数据重新生成子物体,至少能跑起来。