栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

LookRotation用法详解 Unity3d Quaternion.LookRotation实现原理

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LookRotation用法详解 Unity3d Quaternion.LookRotation实现原理

public static Quaternion LookRotation (Vector3 forward, Vector3 upwards= Vector3.up);
官方解释:
使用指定的 forward 和 upwards 方向创建旋转。
Z 轴将与forward对齐,X 轴与 forward 和 upwards 之间的差积对齐,Y 轴与 Z 和 X 之间的差积对齐。 如果
forward 或 upwards 量值为零,则返回恒等。 如果 forward 和 upwards 共线,则返回恒等。

文档写得很官方,自己研究了一会,总的来说,
LookRotation的作用就是将方向转化为旋转角度:传入一个方向将返回一个旋转角,当某个物体被施加这个旋转角后,这个物体的forward方向将指向传入的方向。
这个方法常常配合transform.rotation = Quaternion.LookRotation()使用
 


实验演示: 搭建场景,编写脚本

实验内容:在场景中新建一个正方体和球体,用LookRotation方法将正方体“看向”球体,并绘制输出3条射线。

挂载到正方体上的脚本内容

public class Test: MonoBehaviour{
    public Transform sphere;

    void Update(){
        Vector3 dir = sphere.position - transform.position;  //正方体指向球体的向量dir = 球体坐标 - 正方体坐标
        Quaternion ang = Quaternion.LookRotation(dir);  //创建一个 使正方体“看向”球体的旋转角
        transform.rotation = ang;

        Debug.DrawRay(transform.position, ang.eulerAngles, Color.red);  //即:绘制正方体的旋转轴
        Debug.DrawRay(transform.position, transform.forward * 100, Color.blue);  //绘制正方体forward方向
        Debug.DrawRay(transform.position, dir, Color.green);  //绘制向量dir
    }
}
运行场景,第一个参数解析:

Vector3 dir = sphere.position - transform.position;
Quaternion ang = Quaternion.LookRotation(dir);

  • 绿色射线:以向量dir为方向。
  • 蓝色射线:以正方体forward为方向,与绿色射线部分重合。
  • 红色射线:以四元数ang为方向,是正方体的旋转轴线。

将ang赋值给正方体rotation,正方体的forward方向就指向了目标物体(球体)。直接调试绘制ang将得到一条"奇怪"的射线,因为LookRotation()本身只是用来控制具体物体的旋转的。
 
传入一个Vector3方向将返回一个Quaternion旋转角,某个物体被施加这个旋转角后,这个物体的forward方向将对齐至传入的Vector3方向。
 

场景升级,第二个参数解析

LookRotation的第二个参数upwards影响物体的up和right的方向(即影响Z轴旋转),继上续代码即:
transform.right == Vector3.Cross(sphere.postion - transform.postion, upwards).normalized;
transform.up == Vector3.Cross(sphere.postion - transform.postion, transform.right).normalized;


调节圆锥的Rotation属性正方体的right、up方向受到了影响↑,核心代码如下↓

transform.rotation = Quaternion.LookRotation(sphere.position - transform.position, cone.up);  //第二个参数cone.up将影响正方体的right、up方向
  • 圆锥起点绿色射线:方向为圆锥的+Y轴,即cone.up方向。
  • 圆锥起点红色射线:方向为Vector3.Cross(sphere.position - transform.position, cone.up)。
    仔细看上图,无论怎么旋转圆锥,圆锥起点红色射线和正方体红色箭头(right方向)始终方向相同、保持平行。
     
    若指定第二个参数upwards,则物体的right方向将对齐至‘第一个参数’与‘第二个参数’的叉乘方向。


补充:代码实现LookRotation()
    public Quaternion LookRotation(Vector3 forward)
    {
        float x = Mathf.Acos(Mathf.Sqrt((forward.x * forward.x + forward.z * forward.z) / (forward.x * forward.x + forward.y * forward.y + forward.z * forward.z))) * Mathf.Rad2Deg;
        if (forward.y > 0) x = 360f - x;

        float y = Mathf.Atan2(forward.x, forward.z) * Mathf.Rad2Deg;
        if (y < 0 || forward.x < 0) y += 180f;

        return Quaternion.Euler(x, y, 0f);
    }

这样一个简单LookRotation就实现了,如果还需要实现带第二个参数的方法,只需求出transform.up与LookRotation()返回值之间的夹角就行了。已知两向量求其夹角的公式:
θ = atan ⁡ 2 ( ( A ⃗ × B ⃗ ) ⋅ norm ⁡ ( ) , A ⃗ ∗ B ⃗ ) begin{matrix} theta = operatorname{atan} 2((vec{A} times vec{B}) cdot operatorname{norm}(), vec{A} * vec{B}) end{matrix} θ=atan2((A ×B )⋅norm(),A ∗B )​
但可惜LookRotation()方法内部没法直接拿到transform.up的值,所以我们只能通过数学方式间接的求出transform.up。
初始时,transform.up、LookRotation()返回值、Y轴一定是共面的,且transform.up ⊥ LookRotation()返回值,根据这两个条件联立方程我们就可以准确求出transform.up的值。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901537.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号