关于Unity3D中lossyScale的一点思考

在Unity3D中,transform的lossyScale这个属性使用情况并不多,因此很多人对其没什么了解,笔者最近在做和Unity3D有关的服务器工作,需要了解其来源,因此对其做了一点研究。

在Unity3D的官方文档里,是这样介绍lossyScale的:

然而,这样的介绍,对实现该属性并无多大意义,当然,为什么要实现该属性,因为Unity3D中的基本碰撞体是使用lossyScale伸缩的,以保证基本碰撞体不变形,如下图所示:

Box的RenderMesh已经变形成平行四面体,但BoxCollider仍然是长方体,至于为什么BoxCollider不能变形成平行四面体,是受制于其物理引擎PhysicX未提供平行四面体。

该限制只限于基本碰撞体,对于MeshCollider(无论是否是凸包)则不存在这一限制,如下图所示:

 

好了,扯了这么多,无非是想说lossyScale还是有点用的,计算该值是有必要的,那么如何通过层级Transform的localPosition, localRotation和localScale来计算lossyScale呢?

回到基本的矩阵变换,我们有:

如果知道M, T和R,我们就能得到代表伸缩的S矩阵:

伸缩矩阵S和lossyScale到底有什么关系呢,通过实验发现lossyScale是伸缩矩阵对角线元素,我们构建了一个两层的GameObject:

随便设置下GameObject和Cube的transform:

 

计算lossyScale并对比的代码如下图所示:

结果如下图所示:

很明显的可以看到,lossyScale就是变换矩阵MS矩阵的对角线元素。

public class ObstacleCollect : MonoBehaviour
{
    void Awake()
    {
        BoxCollider[] boxColliders = GetComponentsInChildren<BoxCollider>();
        for (int i = 0; i < boxColliders.Length; i++)
        {
            float minX = boxColliders[i].transform.position.x -
                         boxColliders[i].size.x*boxColliders[i].transform.lossyScale.x*0.5f;
            float minZ = boxColliders[i].transform.position.z -
                         boxColliders[i].size.z*boxColliders[i].transform.lossyScale.z*0.5f;
            float maxX = boxColliders[i].transform.position.x +
                         boxColliders[i].size.x*boxColliders[i].transform.lossyScale.x*0.5f;
            float maxZ = boxColliders[i].transform.position.z +
                         boxColliders[i].size.z*boxColliders[i].transform.lossyScale.z*0.5f;
            Debug.Log(i+ "position  " + boxColliders[i].transform.position.x);
            Debug.Log(i + " size " + boxColliders[i].size.x);
            Debug.Log(i + " lossyScaleX " + boxColliders[i].transform.lossyScale.x);
            Debug.Log(i + "minX  " + minX);
            Debug.Log(i + "maxX  " + maxX);
            Debug.Log(i + "position  " + boxColliders[i].transform.position.z);
            Debug.Log(i + " size " + boxColliders[i].size.z);
            Debug.Log(i + " lossyScaleZ " + boxColliders[i].transform.lossyScale.z);
            Debug.Log(i + "minZ  " + minZ);
            Debug.Log(i + "maxZ  " + maxZ);

            //Debug.Log(boxColliders[i].transform.position.x);


            IList<Vector2> obstacle = new List<Vector2>();
            obstacle.Add(new Vector2(maxX, maxZ));
            obstacle.Add(new Vector2(minX, maxZ));
            obstacle.Add(new Vector2(minX, minZ));
            obstacle.Add(new Vector2(maxX, minZ));
            Simulator.Instance.addObstacle(obstacle);
        }
    }

    // Update is called once per frame
    void Update()
    {
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值