Unity中关于3D数学的个人笔记

这个东西很重要,现在很多功能做不出来或者做的慢,不管是官方文档讲的不详细,还是大学里没有相关课程,但归根结底功能实现起来困难,还是因为这个掌握不熟练。

今天稍微系统的学习了一下3D数学,写下一些笔记。

目录:

         Unity中的四种坐标系

         Unity物体位置变换类详细笔记

         点和向量


 

Unity中的四种坐标系

为了准确灵活的操作游戏物体,Unity提供了四种坐标系,供我们使用。

全局坐标系:

没啥好说的,世界,(0,0,0)为原点。

局部坐标系:

把物体当作一个单独的世界,物体中的一个点当作原点,改变全局坐标,不会影响局部坐标系。

这个东西就好像,一个人和世界的关系。首先把这个人的胃部,当作他局部坐标系的原点,然后假设他的头部的局部坐标是(0,1.5,0),然后你把一个人从(0,0,0)移动到(0,1,0),这个人的世界坐标系发生了改变,但是这个人头的局部坐标不会发生改变,还是相对于胃部的坐标是(0,1.5,0)的位置。

屏幕坐标系:

这个需要着重理解,建立在屏幕上的二维坐标系,以像素来定义的。原点在屏幕的左下角(0,0,0)的位置。这个屏幕坐标的在用 Debug一下Input.mousePosition得出结果。

视口坐标系:

首先得知道,这摄像机的渲染原理是什么,也不能说叫原理,一时也想不到什么好的方式描述,姑且叫运作方式吧,首先我们场景中有一个摄像机,这个摄像机所拍摄的画面被铺到Game窗口,然后再新建一个摄像机,把这个摄像机扭向别的方向,但是为什么Game窗口只能显示一个摄像机的拍摄内容?因为Unity中用Depth也就是深度来控制摄像机的渲染顺序,较大值的摄像机将被渲染在较小值的摄像机之上。然后是在相同深度下,我试了下好像是Game窗口显示的是最先被创建出来的摄像机所拍摄的画面(有待进一步考证,但是不太重要),也就是说在场景中有多个摄像机的情况下,多个摄像机按照它们自身的深度,将所拍摄的画面一层一层的铺在Game窗口上,于是深度最大的那一个摄像机所拍摄的画面,就能被我们所看到。然后,有没有发现?这个方式什么类似?对,就是Unity2D游戏开发中的精灵渲染模式。在2D游戏中,我们把两个sprite,通过拖动,把他俩堆到一起,是谁遮住谁呢?在同一SortingLayer中的Order in Layer中越大的那个越在上面显示,也就是说,这些精灵也是根据自己的Order in Layer大小,一层层的铺的,现在我们把两个正方形的sprite通过拉伸,平铺满整个摄像机所能拍摄的范围。这就形成了,类似于分屏的效果。同理,摄像机通过调节ViewPort,就能实现分屏显示的效果。

知道了上面的这些的话,然后是这个坐标系是相对于显示区域来说的,把屏幕坐标单位化,但是实际上与其这么说,不如说是把屏幕比例化。因为在这个坐标系下,左下角坐标是(0,0),右上角的坐标是(0,1)。举个例子,(0,0.5),这个坐标就是在屏幕高度一半的位置。

而且关于这个视口坐标系的描述以及作用啥的,网上搜了半天都没有实际靠谱的,都是笼统的粘贴复制。这里我做了个简陋的实验。下图:

Unity中关于3D数学的个人笔记_第1张图片

结合层级视图、Game窗口、Scnece视图以及相机的属性面板,就能发现这个视口坐标系是干什么的。

Unity物体位置变换类详细笔记

LookRotation(注视旋转):

public static Quaternion LookRotation (Vector3 forward, Vector3 upwards= Vector3.up);

这个方法,文档的解释真的是不太好理解,但是实际上就是让一个物体的z轴,以第二个参数为轴(这个参数默认给的是Vector3.up),旋转到与forward向量指向的方法对齐,并返回该旋转之后的rotation四元数。(返回的这个四元数是按物体已经旋转到了你规定的那个forward方向的那个四元数,通俗来来说就是目的地的方向的rotation四元数)然后,就可以把返回的四元数的值赋给transform.rotation了,这个API使用的难点是构建forward向量,然后还有就是别看它给的第一个这个形参名字,很有误导作用啊有没有?倒不如把这个参数改为TargetDir。

 

Transform.forward和Vector3.forward以及相关的东西

这两个根本区别照我的理解是一个是第一个是局部坐标,第二个是世界坐标。同理,其他这一套的的API也是一个意思。

 

transform.Translate(translation:Vector3, relativeTo: Space = Space.Self);;

注意下后面那个参数就行。Self是局部坐标系,world是世界坐标。

 

Transform.TransformPoint(Vector3 position) ;

将一个坐标点从局部坐标系转换到全局坐标系。

 

Transform.InverseTransformPoint(Vector3 position);

将坐标点从全局坐标系转换到局部坐标系

 

Transform.TransformDirection(Vector3 direction);

将一个方向从局部坐标系转换到全局坐标系。

 

Transform.InverseTransformDirection(Vector3 direction);

将一个方向从全局坐标系转换到局部坐标系。

 

Transform.TransformVector(Vector3 vector);

将一个向量从局部坐标系转换到全局坐标系。

 

Transform.InverseTransformVector(Vector3 vector);

将一个向量从全局坐标系转换到局部坐标系。

 

Camera.ScreenToWorldPoint(Vector3 position);

将屏幕坐标转换为全局坐标。

 

Camera.WorldToScreenPoint(Vector3 position);

将全局坐标转换为屏幕坐标。

 

Input.mousePosition;

获得鼠标在屏幕坐标系中的坐标。

 

Camera.ScreenToViewportPoint(Vector3 position);

将屏幕坐标转换为视口坐标。

 

Camera.ViewportToScreenPoint(Vector3 position);

将视口坐标转换为屏幕坐标。

 

Camera.WorldToViewportPoint(Vector3 position);

将全局坐标转换为视口坐标。

 

Camera.ViewportToWorldPoint(Vector3 position);

将视口坐标转换为全局坐标。

 

点和向量

点和向量基本知识点

  1. Unity用Vector2、Vector3类型,来表示2D和3D中的环境下的点和向量,即(x,y),(x,y,z)。
  2. 零向量既无大小也无方向,2D零向量表示为(0,0),3D零向量表示为(0,0,0),在Unity中,用Vector3.zero来表示3D零向量。
  3. 给一个向量加负号,使该向量方向变相反
  4. 在Unity中,可以通过Vector3.magnitude计算向量的长度。Vector3.sqrMagnitude则返回向量长度的平方。Vector3.Distance(A,B)可以计算2个点A,B之间的距离,即返回向量AB或向量BA的长度。等同于(B-A).magnitude或(A-B).magnitude。
  5. 单位向量,即用normalizated,这个把向量的长度设为1,方向不变,方便计算和改变长度。

向量的加减法

至今没用过向量之间的加减法,等用到再记下来。

只用过点与点之间相减,构造向量的。

 

向量的点乘运算以及其意义和使用示例

数学公式是这个:|a|*|b|*Cos

Unity中用是这个。

 

Unity中关于3D数学的个人笔记_第2张图片

然后记住这个表:可以看到0到90°都是正数。先把俩向量归一化,再绝对值乘以绝对值再乘以Cos夹角,由下表的值,就可以用来当作确切的夹角范围,一般用来判断一个点是否在另一个点的一定范围内。这个范围通常是扇形。

Unity中关于3D数学的个人笔记_第3张图片

 

向量的叉乘预算以及其意义和使用示例

数学公式:|a|*|b|*Sin

然后:叉积得到的向量垂直于原来的两个向量,也就是说可以拿这个求一个平面的法向量。

Unity中API为

Unity中关于3D数学的个人笔记_第4张图片

其他内容,有待补充。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Unity)