美文网首页
非等比例缩放导致的问题

非等比例缩放导致的问题

作者: 烂醉花间dlitf | 来源:发表于2021-02-20 16:42 被阅读0次

圆形组件不会适配

如果在物体上有球形或者圆形的组件(Sphere Collider , Capsule Collider , Light and Audio Source 等),那么将这个物体非等比例缩放,他们不会自动适配


旋转时产生歪斜

这里有两个正方体,物体关系如下:


父子关系
场景中的视图

Parent 是非等比例缩放的(缩放比例为1,0.2,1),Child 是等比例缩放的(缩放比例为 1,1,1)。
在旋转子物体的时候会产生歪斜:


旋转时产生歪斜

这种情况有一种比较麻烦,但也是目前找到的唯一办法,就是在两个物体中间使用一个空物体进行阻隔,先在最外面新建一个空物体,再把它移到 Parent 里面(不能直接在 Parent 底下新建一个空物体,不然不能平衡缩放)。


层级结构

这时,这里的 Parent 缩放依然是(1,0.2,1),EmptyObject 的缩放是(1,5,1),相乘就是 (1,1,1),也就是将非等比例缩放变成等比例缩放,这样再旋转 Child,就不会出现歪斜了。


不会出现歪斜

通过这种方式,其实可以很自然的想到在 SetParent 的时候手动平衡他的缩放就可以了,于是写了以下代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.Assertions;

public class NewBehaviourScript : MonoBehaviour
{

    public GameObject p;
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Transform t = transform.parent == null ? p.transform : null;
            SetParent(transform, t);
        }
    }

    private void SetParent(Transform child,Transform targetParent)
    {
        Vector3 position = child.position;
        Quaternion rotation = child.rotation;
        Vector3 new_scale = child.lossyScale;
        if (targetParent != null)
        {
            new_scale.x /= targetParent.lossyScale.x;
            new_scale.y /= targetParent.lossyScale.y;
            new_scale.z /= targetParent.lossyScale.z;
        }
        child.SetParent(targetParent,false);
        transform.localScale = new_scale;
        child.position = position;
        transform.rotation = rotation;
    }
}

但实验结果显示这样写并没有什么卵用。

解除父子关系时会出现跳变

前面说到子物体的父物体如果是非均匀缩放的,那么在旋转的时候会出现歪斜,这是因为处于性能的考虑,不会实时更新子物体的缩放。但是当歪斜状态解除父子关系时,子物体的缩放状态被更新,就会突然变成正常的状态。详情看下动图:


总结

如果使用到了非均匀缩放一定要慎重!因为这种夸张的形变是叠加的,像下面这样:


恐怖的形变

代码只是不停的改变 Child 的父物体而已,如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.Assertions;

public class NewBehaviourScript : MonoBehaviour
{

    public GameObject p;
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Transform t = transform.parent == null ? p.transform : null;
            transform.SetParent(t);
            //SetParent(transform, t);
        }
    }
}

参考

Unity Manual Limitations with Non-Uniform Scaling

相关文章

网友评论

      本文标题:非等比例缩放导致的问题

      本文链接:https://www.haomeiwen.com/subject/nwfxfltx.html