LookAt函数的定义如下

void LookAt(Transformtarget,Vector3worldUp = Vector3.up);

target    :Object to point towards
worldUp:Vector specifying the upward direction.

根据官方的文档描述,该函数的功能是,旋转自身,使得当前对象的正z轴指向目标对象target所在的位置。

而对于worldUp的描述是,在完成上面的旋转之后,继续旋转自身,使得当前对象的正y轴朝向与worldUp所指向的朝向一致。这里所说的朝向一致并不是指两个向量方向完全一致,这就是让人迷惑的地方。

现使用一个例子进行解析

使摄像头指向一个物体,摄像头的位置是(0,30,60),目标物体的位置是(0,0,0),代码如下

using UnityEngine;
using System.Collections;public class lookAtTest : MonoBehaviour {// Use this for initializationpublic Transform target;void Start () {target.position = Vector3.zero;        transform.position = new Vector3(0, 30, 60);Vector3 diff = target.position - transform.position;transform.LookAt(target);        }
}

现在为了解析LookAt函数的计算过程,使用如下代码:

using UnityEngine;
using System.Collections;public class lookAtTest : MonoBehaviour {public Transform target;    void Start () {target.transform.position = Vector3.zero;        transform.position = new Vector3(0, 30, 60);Vector3 diff = target.position - transform.position;Quaternion q = Quaternion.FromToRotation(Vector3.forward, diff);Vector3 newUp = q * Vector3.up;Quaternion qNew = Quaternion.FromToRotation(newUp,Vector3.up);transform.rotation = qNew * q;        }
}

该计算过程中,q的计算是正确的,qNew的计算是将新旋转后的y轴旋转到Vector3.up,经过这样运算后和前面LookAt的运行结果比对可以发现该计算是错误的。错误发生在qNew的计算上。

经过多次测试后发现,worldUp的描述“在完成上面的旋转之后,继续旋转自身,使得当前对象的正y轴朝向与worldUp所指向的朝向一致”里的朝向一致,指的是新旋转后的y轴与worldUp在该对象初次旋转后的xy平面上的投影向量一致。也就是说,worldUp应取它在应用了旋转量q后的xy平面的投影量

新代码如下

using UnityEngine;
using System.Collections;public class lookAtTest : MonoBehaviour
{public Transform target;void Start(){target.transform.position = Vector3.zero;transform.position = new Vector3(0, 30, 60);Vector3 diff = target.position - transform.position;Quaternion q = Quaternion.FromToRotation(Vector3.forward, diff);Vector3 n = q * Vector3.forward;Vector3 worldUp = Vector3.up;float dirDot = Vector3.Dot(n, worldUp);Vector3 vProj = worldUp - n * dirDot;    //worldUp在xy平面上的投影量vProj.Normalize();float dotproj = Vector3.Dot(vProj, newUp);float theta = Mathf.Acos(dotproj) * Mathf.Rad2Deg;Quaternion qNew = Quaternion.AngleAxis(theta, n);        Quaternion qall = qNew * q;transform.rotation = qall;}}

Transform.LookAt解析相关推荐

  1. 【 unity3d 】Transform.LookAt()方法

    Transform.LookAt()方法 public void LookAt (Transform target); 旋转当前脚本对象,让向前向量z指向target的当前位置.简单说,旋转物体使z轴 ...

  2. Unity3d C#解决transform.LookAt朝向前后翻转问题(含源码)

    一修改模型 transform.LookAt功能是当前节点的Z 轴正方向看向指定节点,所以让模型人员协助修改坐标系即可以解决该问题,使模型的正向为z轴即可. 二加节点修正 一的方式也可以自己来修正,就 ...

  3. 归一化(Normalization)标准化(Standarlization)tensorflow和opencv区别:opencv之transform函数解析CHW与HWC:图像的线性数据格

    目录 归一化:transforms.Normalize 归一化(Normalization) 标准化(Standarlization) tensorflow和opencv区别:opencv之trans ...

  4. Unity3d LookAt参数说明

    Unity3d LookAt参数说明  //// 摘要: // Rotates the transform so the forward vector points at target's curre ...

  5. Unity(TransForm)

    #一.描述 此课程讲解TransForm的定义以及使用方法 #二.简介说明 TransForm是对游戏对象的移动,旋转,缩放做操作的,并且如果一个游戏对象他没有父布局的话,他的作用的坐标是世界坐标,如 ...

  6. unity头顶状态制作_Unity中结合IK实现Lookat

    前言 之前只是花个周末复读了一篇育碧的演讲,讲到一些周边系统,程序化镜头,口型匹配,角色补光,景深,Lookat,我都玩过一点,很多在2U引擎里都算是标配;本以为投靠Unreal可以缓解大部分周边系统 ...

  7. Unity3D 的LookAt() 与 LookRotation()方法的比较

    LookAt(),定义: 其定义在UnityEngine.Transform类中, public void LookAt(Vector3 worldPosition); public void Loo ...

  8. Unity 在2D中实现LookAt

    由于Transform.LookAt是使Z轴看向目标,而2D基本是由X和Y轴构成的.所以在2D的游戏中,不太好使用. 所以用代码实现一个2D的LookAt函数. 例子: 我们使怪物的眼睛一直看着云. ...

  9. Unity中,区别LookAt与LookRotation

    详细的资料可以看这个大佬总结的:参考资料 我这里直接用图结合着说: 首先呢,我们的主角要看向敌人,下图是还没看向之前: 使用LookAt函数看向敌人后,Z轴看向敌人(也是正面看向敌人) 而如果Look ...

最新文章

  1. android EditText 限定中文个数与英文个数的解决方式
  2. 设计模式C#描述——单例与多例模式
  3. python初学工资-python工资高还是java?
  4. 泛型--定制泛型接口、泛型类--介绍篇
  5. python字符串是什么_python字符串表示什么
  6. 充分条件反过来是必要条件吗_“充分必要条件”引发的现实思考
  7. c++ 获取文件夹创建时间_手把手教学免费创建个人网站
  8. 小毛驴走呀走的openeim001
  9. django类视图简单使用和源码解析
  10. 游戏工委:已有63家单位响应防止未成年人沉迷通知
  11. 计算机应用基础图表填空,计算机应用基础填空题.doc
  12. C语言库函数——string.h
  13. 无痛学习ISAC(一)
  14. 在Virtualbox虚拟机中安装MSDOS(简易教程)
  15. 计算机添加本地安全组用户名和密码错误,win7系统访问远程共享文件夹提示未知的用户名或密码错误的解决方法...
  16. mysql8+maven+mybatis
  17. PHP单元测试框架 - PHPUnit介绍
  18. 滚铁环,跳橡皮筋,斗鸡,打弹珠,老鹰捉小鸡…………
  19. 数据吞吐量高达800亿条!实时计算在贝壳找房的应用实践
  20. Android流媒体开发之 自定义一个完备的log模块

热门文章

  1. IKBC键盘win键失灵解决方法
  2. 2022-03-27 screenX和clientX的区别以及offsetX和pageX的区别
  3. 浅谈SAP顾问未来十年在中国的发展前景
  4. TP6使用守护进程完成队列任务
  5. 计算机二级考试场次是随机的,计算机二级考试知多少
  6. 核心单词Word List 46
  7. 华为云云享专家申请流程
  8. 思科交换机IOS备份和升级
  9. 网页上做笔记--Diigo
  10. Symfony4.1 Routing 基础