C#程序员整理的Unity 3D笔记(十):Unity3D的位移、旋转的3D数学模型
遇到一个想做的功能,但是实现不了,核心原因是因为对U3D的3D数学概念没有灵活吃透。故再次系统学习之—第三次学习3D数学.
本次,希望实现的功能很简单:
如在小地图中,希望可以动态画出Player当前的位置、z的朝向:用3条线、z轴正向、30°旋转、-30°旋转。
问题是:0点可以获得,P1点? P2点是未知的。
我尝试了2个小时,结果不竟如人意,少于沮丧。
不得不,再次花点时间系统的学习3D数学:
1 位移–向量和点:
- 点: 点和向量在数学上是一致的,实际生活中点的概念比较好理解,坐标点来定位–南二环、北二环。 【点用(3,4,5)圆括号来标示,简称P】
- 向量:“俗称增量”,有大小和方向,如”往前1步走。 左转90度”. 往前走,直到碰到墙,你才会停下来—在这之前,你无法准确获得碰到墙的点的坐标或者你和墙的距离。 【向量用<3,4,5>尖括号来标示,简称V】
- 在U3D中,统一用Vector3对象来表达向量和点,这个也是导致新手晕头转向的一个很重要的原因; 一个技巧,凡是在API中用position、Point的,V3肯定代表是点;凡是Vector、direction的是向量;多看官方的API手册,写得很明白。
做个游戏,列表出你用过的Vector3的API,分析分析用到的Vector3是向量(V)还是点(P)
需求 |
API |
向量(V) 点(P) |
备注 |
平滑位移 |
Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta); |
P |
|
平滑位移 |
Vector3 Slerp(Vector3 from, Vector3 to, float t) |
P |
|
新的坐标点 |
this.m_transform.position = pos; |
P |
符合常规思维 |
变动一次坐标 |
m_transform.Translate(new Vector3(rx, 0, -m_Speed * Time.deltaTime)); |
V |
可认为是增量 |
求方向 |
Vector3 relativePos = this.m_transform.position – m_Player.position; |
V |
向量减法,较难理解 |
设置新坐标点 |
lineRenderer.SetPosition(0,this.gameObject.transform.position); m_NavAgent.SetDestination(this.m_Player.transform.position); |
P |
符合常规思维 |
新的位置 |
pointer.transform.position = hitInfo.point + (transform.position – hitInfo.point) * 0.01f; |
P、V |
力的叠加? |
求距离 |
float dis = Vector3.Distance(v1, v2); float f1 = (v1 – v2).sqrMagnitude; float f3 = (v1 – v2).magnitude; |
P、V |
Distance用点即可 向量减法也可以 |
缩放正向 |
Vector3 v3 = this.m_transform.forward * 200f; |
V |
V的数乘 |
射线检测 |
Ray r = new Ray(source, dest); Physics.Raycast(r, out hit, 1000, m_ShootMask) |
V、P |
Source:P Dest:V |
加一个力 |
rigidbody.AddForce (0, 10, 0); |
V |
依据这个游戏,可以整理出目前用到的有4个组件(含Vector 3)会发生位移:
位移常用的4个组件和Vector3:
组件 |
函数 |
Unity 圣典的API说明 |
是否 用过 |
transform组件 |
translate函数 |
向某方向移动物体多少距离【默认local坐标系】 或者相对某物体移动 |
yes |
Position属性 |
在世界空间坐标transform的位置 |
Yes |
|
RigidBody组件 [FixedUpdate函数] |
Velocity属性 |
刚体的速度向量 Unity 官方demo Done用的很酷 |
Yes |
AddForce函数 |
添加一个力到刚体。作为结果刚体将开始移动。 |
yes |
|
MovePosition函数 |
移动刚体到position |
||
NavMeshAgent组件 |
SetDestination函数 |
设置自动Path目标点 |
yes |
CharacterController 组件 |
Move函数 |
一个更加复杂的运动函数,每次都绝对运动 |
yes |
SimpleMove函数 |
以一定的速度移动角色 |
||
Vector3向量 |
Lerp函数 |
两个向量之间的线性插值。 “像弹簧一个跟随目标物体” |
|
Slerp函数 |
球形插值在两个向量之间 “在日出和日落之间动画弧线” |
||
MoveToward函数 |
当前的地点移向目标 和Vector3.Lerp相同,maxDistanceDelta限速 |
||
SmoothDamp 函数 |
随着时间的推移,逐渐改变一个向量朝向预期的目标。 |
我的几个向量相关的问题:
- 如何判断A向量和B向量是否同方向?
- 如何判断A向量和B向量前、后、左、右?
- 如何判断A向量和B向量的夹角?
- 向量的减法貌似比加法更有用一些?
- Vector.Forward和this.transform.Forward都表达local坐标系,那么数值为什么不一样呢?
2 旋转–Quaternion、eulerAngles、Quaternion.Euler
旋转在3D中是比较复杂的,在Unity 3D中一般用Quaternion来进行旋转, 旋转仅涉及向量的概念(向量的方向),请思考对于坐标点或者零向量旋转有无意义?
而按照Unity 3D API官方的说法,仅有约7个方法或者操作符比较常用,且占99%的概率,我截止目前还没有用到这么多,我用到的Quaterniong约有4个函数。
旋转常用7个API:
Quaternion API |
Unity 圣典的API说明 |
是否 用过 |
Quaternion.LookRotation |
创建一个旋转,沿着forward(z轴)并且头部沿着upwards(y轴)的约束注视。也就是建立一个旋转,使z轴朝向y轴朝向up。 常用的是transform.LookAt |
yes |
Quaternion.Angle |
返回a和b两者之间的角度。 |
|
Quaternion.Euler |
返回一个旋转角度,绕z轴旋转z度,绕x轴旋转x度,绕y轴旋转y度(像这样的顺序)。 |
yes |
Quaternion.Slerp |
球形插值,通过t值from向to之间插值。 |
|
Quaternion.FromToRotation |
从fromDirection到toDirection创建一个旋转。 |
|
Quaternion.identity |
返回恒等式旋转(只读)。这个四元数对于“无旋转”:这个物体完全对齐于世界或父轴。 |
yes |
Quaternion.operator * |
由另一个四元数来旋转一个旋转角度,或由一个旋转角度来旋转一个向量 |
yes |
我的几个旋转相关的问题:
1 Quaternion.LookRotation和Vector3.RotateTowards的区别?
2 Quaternion.Angle和Vector3.Angle的区别?
3 Quaternion.LookRotation和transform.LookAt的区别?
[官方回答: 大多数时间你可以使用transform.LookAt代替
Quaternion.LookRotation]
4 如何实现2个GameObject face to face,即Z轴相对?
磨刀不误砍柴工: 经过一周的复习、反复验证,果然在系统学习3D 数学后,要实现的功能可以了,如下:
参考博客:
坐标系的简介:C#程序员整理的Unity 3D笔记(八):Unity 3D坐标系介绍
宣雨松的博客:http://www.xuanyusong.com/archives/1977
总结:
据说80%、90%Unity 3D程序员是自学的,大多数是看看书、实战视频、源码分析;而科班出生的同学会有3D数学这门核心课–估计占一个学期、会有作业等。为了赶上科班同学的水平,花点时间,补补数学知识,会使得自己少走一些弯路。一句话:”3D数学模型很关键。“
C#程序员整理的Unity 3D笔记(十):Unity3D的位移、旋转的3D数学模型的更多相关文章
- C#程序员整理的Unity 3D笔记(十五):Unity 3D UI控件至尊–NGUI
目前,UGUI问世不过半年(其随着Unity 4.6发布问世),而市面上商用的产品,UI控件的至尊为NGUI:影响力和广度(可搜索公司招聘Unity 3D,常常能看到对NGUI关键词). NGUI虽然 ...
- C#程序员整理的Unity 3D笔记(十三):Unity 3D基于组件的思想
如果你接触过<设计模式>.软件架构的编程思想,就会知道优秀的设计准则:“组合优于继承的”. 这句话很简短,但开始学习OOP的时候,真切的是—-不太好理解(以我个人当初学习为例). OOP的 ...
- 【转载】国外程序员整理的Java资源大全
以下转载自: 推荐!国外程序员整理的Java资源大全中文版 https://github.com/akullpp/awesome-java英文版 Java 几乎是许多程序员们的入门语言,并且也是 ...
- 推荐!国外程序员整理的 PHP 资源大全
推荐!国外程序员整理的 PHP 资源大全 2014/08/02 · PHP, 工具与资源 · 8.5K 阅读 · 1 评论· php 分享到:0 与<YII框架>不得不说的故事—安全篇 R ...
- 《程序员思维修炼》读书笔记——week4
<程序员思维修炼>读书笔记——week4 PB16061441 陈昶金 这周读的是Andy Hunt的著作<程序员思维修炼>,这本书对于我这种刚刚入门的新手很友好,大多是讲一些 ...
- 国外程序员整理的Java资源大全分享
Java 几乎是许多程序员们的入门语言,并且也是世界上非常流行的编程语言.国外程序员 Andreas Kull 在其 Github 上整理了非常优秀的 Java 开发资源,推荐给大家. 译文由 Imp ...
- 【转】国外程序员整理的Java资源大全
Java几乎是许多程序员们的入门语言,并且也是世界上非常流行的编程语言.国外程序员Andreas Kull在其Github上整理了非常优秀的Java开发资源,推荐给大家.译文由ImportNew- 唐 ...
- 【185天】黑马程序员27天视频学习笔记【Day14-下】
叨逼叨两句 不容易,白天被叫去帮忙,不得已晚上来挑灯夜战,熬到2点,总算完成任务了. 我打算下周开始换一个更新时间,每次把deadline设置为晚上12点,都会接近或者超过这个时间,之后改成中午12点 ...
- 【干货】国外程序员整理的 C++ 资源大全【转】
来自 https://github.com/fffaraz/awesome-cpp A curated list of awesome C/C++ frameworks, libraries, res ...
随机推荐
- (原创)vagrant up 异常报错,出现 There was an error while executing `VBoxManage` 的解决方法
最近在使用 vagrant homestead 时,不小心在虚拟机上使用了 exit 命令退出虚拟机,导致再使用 vagrant up 时出现以下错误: Bringing machine 'larav ...
- XMPP——Smack[1]连接、登陆及账户操作
临毕业前,应需求,花了三天写了个小的聊天工具,貌似简陋得很….若有机会再完善吧,目前毕业季,处理毕业事宜,还要准备即将的入职. 眼瞅着大学四年就这么结束了,哎. 开始吧,四篇博文简单介绍下基本实现,由 ...
- java 实现视频转换通用工具类:视频相互转换-Ffmpeg(三)
java 实现视频转换通用工具类:获取视频元数据信息(一) java 实现视频转换通用工具类:视频相互转换-总方法及Mencoder(二) 这节主要是ffmpeg的相关方法封装,在实际调用中主要使用f ...
- JS 数据类型转换-转换函数、强制类型转换、利用js变量弱类型转换
1. 转换函数: js提供了parseInt()和parseFloat()两个转换函数.前者把值转换成整数,后者把值转换成浮点数.只有对String类型调用这些方法,这两个函数才能正确运行:对其他类型 ...
- 从零开始学android开发-Json转换利器Gson之实例
Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库.可以将一个 JSON 字符串转成一个 Java 对象,或者反过来. jar和源码下载地址: h ...
- 将图片序列保存为GIF文件
http://stackoverflow.com/questions/11459568/issue-with-rebuilding-and-saving-gifs-using-tgifimage 将图 ...
- Oracle Hints具体解释
在向大家具体介绍Oracle Hints之前,首先让大家了解下Oracle Hints是什么,然后全面介绍Oracle Hints,希望对大家实用.基于代价的优化器是非常聪明的,在绝大多数情况下它会选 ...
- [Effective C++ --006]若不能使用编译器自动生成的函数,就该明确拒绝
■本文内容■□第一节 <引言> 在条款五的讲解中,我们已经知道编译器是聪明的家伙,它会帮助你生成类的构造函数.析构函数.一个copy构造函数和一个赋值运算符.有时真的要感谢编译器所做的这一 ...
- mysql数据库常用语句2
关于mysql常用语句的整理,上一篇涉及到ddl.dml以及一些简单的查询语句. 1:mysql分页查询 select * from table_name limit 5,10; 从下标为5元素查 ...
- FullPage.js全屏滚动插件的配置项、方法和回调函数
fullPage.js 是一个基于 jQuery 的插件,它能够很方便.很轻松的制作出全屏网站,主要功能有: 支持鼠标滚动 支持前进后退和键盘控制 多个回调函数 支持手机.平板触摸事件 支持 CSS3 ...