unity动态将3d标牌UI加载到模型子物体下,UI变形问题
//1、直接生成模型
GameObject prefab = GameObject.Instantiate(modeinfo, SelectedModel.transform);
//2、先生成在世界下,再设置为子物体
prefab.transform.SetParent(currentlySelectedModel.transform); //同样SetParent方法默认下也是受父物体影响
该方法是将World Space 模式下的ui生成在 SelectedModel 模型下,即将ui作为子物体。此时ui的缩放值会受其父物体的缩放值的影响,故导致其变形。
以上两种办法都会导致ui变形。
解决方案:
// 需要补偿父物体的变换影响 private void LoadModeInfo() { // 先计算补偿变换 Vector3 parentScale = currentlySelectedModel.transform.lossyScale; Vector3 compensationScale = new Vector3( 1f/parentScale.x, 1f/parentScale.y, 1f/parentScale.z ) * 0.1f; GameObject prefab = GameObject.Instantiate(modeinfo); prefab.transform.SetParent(currentlySelectedModel.transform, false); // false表示不立即应用父物体变换 // 应用补偿缩放 prefab.transform.localScale = compensationScale; //设置3d标牌位于人物中心0.55高度 prefab.transform.localPosition = new Vector3(0, 0.55f, 0); Canvas canvas = prefab.GetComponent<Canvas>(); canvas.worldCamera = Camera.main; }
原理:
补偿计算原理解释
1. 目的
补偿计算是为了抵消父物体 scale 对子物体造成的变形影响,保持子物体在视觉上的正常大小。
2. 计算过程
- 获取父物体的世界缩放
Vector3 parentScale = currentlySelectedModel.transform.lossyScale;
lossyScale 返回物体在世界空间中的实际缩放值,包含了所有父级的缩放影响。
- 计算补偿因子:
Vector3 compensationScale = new Vector3( 1f/parentScale.x, 1f/parentScale.y, 1f/parentScale.z ) * 0.1f;
分解为两步:
1、1f/parentScale - 计算每个轴的逆缩放因子,用于完全抵消父物体的缩放影响
2、* 0.1f - 应用目标缩放值(0.1倍标准大小)
3. 工作原理
当一个物体成为子物体时,它的最终显示大小 = localScale × parent.lossyScale
- 如果不进行补偿,子物体会随父物体缩放而变形
- 通过应用 1/parentScale 的补偿因子,可以抵消父物体的影响
- 最终结果:子物体保持固定大小,不受父物体缩放影响
4. 示例
假设父物体 scale 为 (2, 2, 2):
- 无补偿时子物体实际大小:(1, 1, 1) × (2, 2, 2) = (2, 2, 2) → 放大2倍
- 应用补偿后:(0.05, 0.05, 0.05) × (2, 2, 2) = (0.1, 0.1, 0.1) → 保持0.1倍标准大小
浙公网安备 33010602011771号