Unity中组缩放非1时调整物体角度导致物体变长的问题咨询
Unity组旋转时物体拉伸问题解决
问题分析
你遇到的是Unity变换系统中缩放与旋转顺序冲突导致的典型拉伸问题:Unity对物体的变换计算遵循「局部缩放→局部旋转→局部平移」的顺序,当父物体存在非(1,1,1)的缩放时,旋转父物体会让子物体的局部缩放被父物体的旋转矩阵扭曲,最终在世界空间呈现拉伸变形。只有父物体缩放为(1,1,1)时,旋转操作不会干扰子物体的缩放表现。
(补充截图说明:现象截图显示旋转组后,组内物体沿旋转轴方向出现明显拉伸;层级结构截图显示物体存在清晰的父-子层级,父物体应用了非1的缩放值)
解决方案
1. 烘焙父物体缩放至子物体(推荐)
将父物体的缩放批量应用到所有子物体的局部缩放中,然后重置父物体缩放为(1,1,1),彻底解决旋转与缩放的冲突:
- 编辑器手动流程:
- 选中父物体下所有子物体(层级窗口框选)
- 若子物体是预制体实例,右键选择Break Prefab Instance解除关联
- 记录父物体当前的缩放值
parentScale - 逐个调整子物体的
localScale,将其与parentScale相乘 - 最后把父物体缩放设为
(1,1,1)
- 批量处理代码:
using UnityEngine; public class BakeParentScale : MonoBehaviour { [ContextMenu("Bake Parent Scale to Children")] public void ExecuteScaleBake() { var parentScale = transform.localScale; if (parentScale == Vector3.one) return; foreach (Transform child in transform) { child.localScale = Vector3.Scale(child.localScale, parentScale); // 如需处理嵌套子物体,取消下方注释 // BakeNestedChildren(child, parentScale); } transform.localScale = Vector3.one; } // 递归处理嵌套子层级 private void BakeNestedChildren(Transform parent, Vector3 scaleFactor) { foreach (Transform child in parent) { child.localScale = Vector3.Scale(child.localScale, scaleFactor); BakeNestedChildren(child, scaleFactor); } } }
将脚本挂载到父物体上,右键点击组件选择Bake Parent Scale to Children即可一键完成处理。
2. 分离旋转与缩放层级
若需要保留父物体的缩放控制能力,可调整层级结构规避冲突:
- 创建空物体作为旋转容器,将原父物体设为它的子物体
- 在原父物体上单独控制缩放,在旋转容器上单独控制旋转
- 这种分离方式让旋转和缩放的计算互不干扰,从根源避免拉伸
3. 程序控制缩放的修正方案
如果必须通过代码直接控制父物体缩放,可通过lossyScale计算世界空间缩放比例,同步修正子物体缩放:
// 示例:调整父物体缩放时,保持子物体世界空间尺寸不变 public void UpdateParentScale(Vector3 targetScale) { var oldWorldScale = transform.lossyScale; var scaleRatio = new Vector3( targetScale.x / oldWorldScale.x, targetScale.y / oldWorldScale.y, targetScale.z / oldWorldScale.z ); foreach (Transform child in transform) { child.localScale = Vector3.Scale(child.localScale, scaleRatio); } transform.localScale = targetScale; }
内容的提问来源于stack exchange,提问作者JWC
相关产品推荐
相关产品推荐

