Unity中动画缩小子对象时ContentSizeFitter未更新容器尺寸的问题
问题分析与解决方案
核心问题
你直接修改容器的sizeDelta无效,是因为VerticalLayoutGroup + ContentSizeFitter这两个布局组件会自动计算容器尺寸,覆盖你手动设置的sizeDelta。编辑器拖拽时正常是因为编辑器的布局刷新逻辑和运行时不同,手动操作会临时绕过布局组件的自动计算,但运行时布局系统会每帧(或强制刷新时)重新计算容器大小,把你修改的值覆盖回去。另外容器上的LayoutElement设置了最小高度200,也会在子物体总高度不足时限制容器高度。
正确解决方案
不要直接修改容器尺寸,而是通过修改ObjectB的尺寸,让布局组件自动驱动容器缩小,推荐两种方式:
方式1:修改ObjectB的LayoutElement参数(推荐)
如果ObjectB挂载了LayoutElement,直接调整它的preferredHeight或minHeight,布局组件会自动更新容器大小:
timer = 0f; // 获取ObjectB的LayoutElement组件 var objectBLayout = ObjectB.GetComponent<LayoutElement>(); float startHeight = objectBLayout.preferredHeight; while (timer < 1) { float targetHeight = Mathf.Lerp(startHeight, 0, timer); objectBLayout.preferredHeight = targetHeight; // 可选:如果需要让ObjectB完全消失,同时把minHeight也设为0 // objectBLayout.minHeight = targetHeight; timer += Time.deltaTime * speed; // 强制刷新布局,确保容器尺寸及时更新 LayoutRebuilder.ForceRebuildLayoutImmediate(_buttonReceivedContainer.GetComponent<RectTransform>()); yield return null; } // 动画结束后如果需要恢复容器的最小高度,可在此处理 // var containerLayout = _buttonReceivedContainer.GetComponent<LayoutElement>(); // containerLayout.minHeight = 200;
方式2:修改ObjectB的RectTransform尺寸
如果ObjectB没有LayoutElement,直接修改它的RectTransform的sizeDelta:
timer = 0f; var objectBRt = ObjectB.GetComponent<RectTransform>(); float startHeight = objectBRt.sizeDelta.y; while (timer < 1) { float targetHeight = Mathf.Lerp(startHeight, 0, timer); objectBRt.sizeDelta = new Vector2(objectBRt.sizeDelta.x, targetHeight); timer += Time.deltaTime * speed; LayoutRebuilder.ForceRebuildLayoutImmediate(_buttonReceivedContainer.GetComponent<RectTransform>()); yield return null; }
额外注意点
- 如果容器的LayoutElement设置了最小高度200,当ObjectB缩小后子物体总高度低于200时,容器会被限制在200高度。可以在动画过程中动态修改容器的
LayoutElement.minHeight,比如跟着ObjectB的高度同步降低,动画结束后再恢复。 - 不要禁用布局组件来强制修改容器尺寸,这会导致布局逻辑混乱,后续恢复时容易出现异常。
内容的提问来源于stack exchange,提问作者Luke Warm
相关产品推荐
相关产品推荐

