Unity学习日志_3D数学基础
1. Input类:
InputManager为开发者提供了官方的移动所需的变量。
1. 需要用的静态方法:
- GetAxis(string axisName);返回相应名称的虚拟轴值
- GetAxisRaw(string axisName);未经过平滑处理的GetAxis。
- 不要将Input.GetButton和GetKey系列方法用于物体移动。
- 这两个系列方法的返回值都为bool型,适合用来响应点击事件。
- 使用这两个系列的方法会将物体移动代码的操控写死。
2. Mathf类:
提供大量现成的数学运算的方法和常量。其函数均为静态函数。
舍入方法:Round(四舍五入),Ceil(向小取整),Floor(向大取整)等,三角函数:Cos,Sin,Tan等,限定范围:Clamp等,插值运算,指数运算,对数运算,等等一系列方法。
1. 三角函数:
1. 角度的度量:
- 角度degree
- 弧度radian
2. 角度与弧度转换:
弧度–》角度:数学公式:角度 = 弧度*180/PI;
角度–》弧度:数学公式:弧度 = 角度*PI/180;(求的结果是什么,什么就在分式的分子)
UnityAPI:
弧–》角:弧度*Mathf.Rad2Deg;
角–》弧:角度*Mathf.Deg2Rad;
3. 三角函数:
在unity中已知一边一角求另一边使用三角函数:
sinX = a/c(对边比斜边)
cosX = b/c(临边比斜边)
TanX = a/b(对边比临边)
在unity中已知两个边求角度使用反三角函数:
arcsin(a/c)= x;
arccos(b/c)= x;
arctan(a/b)= x;
UnityAPI提供的函数角度均需要换算为弧度。
UnityAPI提供的三角函数:
Mathf.San(弧度)
Mathf.Cos()
Mathf.Tan()
Mathf.Asin(a/c)
Mathf.Acos(b/c)
Mathf.Atan(a/b)
3. Vector3结构:
1. 向量:
- 有大小(模长)有方向的物理量。
1. 求向量模长:
- UnityAPI提供的变量:
- Vector3变量.magnitude;
- 数学公式:
- Mathf.sqrt(Mathf.Pow(x,2)+Mathf.Pow(y,2)+Mathf.Pow(z,2));
- Vector3.Distance(Vector3.Zero,vector);
2. 求向量方向:
- 求向量的方向也叫:“标准化向量”,“归一化向量”,即获得该向量的“单位向量”。
- 单位向量:模长为1的向量。所以向量的方向仍然是一个向量。
- 求向量方向的方法:
- 数学公式:
- Vector3 vectorDirection = vector/vector.magnitude;
- unityAPI:
- Vector3 vectorDirection = vector.normalized;
- Vector.Normalize();将自身变成自己的向量方向。
- 数学公式:
3. 向量相减:
- 两个向量详相减,结果仍然是一个向量。
- 各分量相减。
- 向量相减其大小为两向量之间的距离。Distance()方法的实现原理。
- 向量相减其方向为减数指向被减数(方向在游戏开发中非常重要)。
- 实际位置要移动到对应坐标系的原点(取决于相减的两个向量)。
- 如果只想要向量相减之后的方向,则需要把差向量标准化,防止受到模长的影响。
- 几何意义:对于a -= b;a向量末端的物体会向着b向量的反方向运动。物体本身方向是箭头的方向。
4. 向量相加:
- 两个向量相加,结果仍为一个向量,这也是Translate()方法的实现原理。
- 各分量相加。
- transform.Translate(vector);挂载本脚本的物体会向着vector向量的正方向移动。
- 几何意义:对于a += b;a向量末端的物体会向着b向量的正方向移动。(Translate内部代码)当然方向是箭头的方向。
5. 向量与标量的乘除(数乘/数除):
- 几何意义:向量模的缩放,方向不变。
- 各分量同时乘/除一个数值。
6. 点乘:
-
又称“点积”或者“内积”。
-
公式:各个分量乘积和。
- [x1,y1,z1]·[x2,y2,z2] = x1x2+y1y2+z1*z2;
-
点积的结果是一个标量。
-
几何意义:a·b = |a|*|b|*cos<a,b>
-
如果两个向量均为单位向量则,a·b = cos<a,b>
-
点乘的几种情况:
- 结果为0:两向量垂直。
- 结果大于0:两个向量的夹角为锐角。
- 结果小于0:两个向量的夹角为钝角。
-
点积的应用:
-
求两个向量之间的夹角的余弦值。之后使用反余弦函数解得弧度或者角度。
- float dot = Mathf.Dot(a1.normalized,a2.normalized);
- Angel = Mathf.Acos(dot)*Mathf.Rad2Deg;
-
判断是否进入攻击范围
-
圆形攻击范围:使用Vector3.Distance判断。
-
扇形攻击范围:使用Vector3.Dot(transform.position+this.transform.forward,playerVector-enemyVector)来判断。判断角度是否小于一个值。小于则说明进入攻击范围。
-
-
7. 叉乘:
- 又称“叉积”或者“外积”。
- 公式:[x1,y1,z1]X[x2,y2,z2] = (y1z2-y2z1,x1z2-x2z1,x1y2-x2y1)。
- 几何意义:结果为一个向量,且为两个向量所组成平面的垂直向量。其模长为两个向量模长的乘积再乘其夹角的正弦值。即|aXb| = |a|*|b|*sin<a,b>。
- UnityAPI:Vector3 vector = Mathf.Cross(a,b);
- 叉乘应用:
- 创建垂直于两向量的向量。
- 判断两个向量的相对位置。
- 判断相对位置,物体在左边还是右边。
2. 欧拉角:
-
使用三个角度来存储物体方位。
-
X和Z沿自身坐标轴旋转,Y沿世界坐标轴旋转。
-
API:Vector3 eulerAngle = this.transform.eulerAngles;
-
与向量不同,这里的欧拉角只是借用了Vector3这个结构体,所以欧拉角并没有方向和大小,其表示的是各个分量的偏移角度。
-
优点:
- 只使用三个数来存储物体方位,占用空间小。
- 沿坐标轴旋转为单位的角度,符合人的思考。
- 任意三个数都是合法的,不存在不合法的欧拉角。
-
缺点:
- (导致角的表示不唯一)为保证每个角度都是唯一的,unity引擎限制了欧拉角的取值:X轴限制在-90到90度,Y,Z轴限制在0到360度。
- 万向节死锁:当物体沿X轴旋转到±90度时,Z轴与世界Y轴会重合,此时再沿Z或者Y旋转时就会失去一个自由度。默认规定此时旋转由Y轴完成,Z轴为0。
4. 四元数结构:
在unity中有单独的Quaternion类。详细方法请参考unity手册。
-
Quaternion在3D图形学中代表旋转,由一个三维向量(X/Y/Z)和一个标量(W)组成。
-
旋转轴为V,旋转弧度为θ。使用四元数来表示则四个分量为:
- qt.x = sin(θ/2)V.x(旋转轴的x分量)
- *qt.y = sin(θ/2)*V.y(旋转轴的y分量)
- qt.z = sin(θ/2)*V.z(旋转轴的z分量)
- qt.w = cos(θ/2)
- 这里的θ为弧度,unity中计算角度都为弧度。
- X,Y,Z,W的取值范围都为-1到1。
-
Inspector面板的rotation为四元数类型,但展示给用户的输入口为欧拉角类型。其内部原理是使用Quaternion.Euler()来将输入的欧拉角转换为四元数。
-
API创建四元数:Quaternion qt = new Quaternion();
-
四元数之间通过相乘实现角度累加的效果:
- qt *= Quaternion.Euler(10,0,0) 等同于下面的欧拉角
- Vector3 vt += new Vector3(10,0,0)
-
四元数的优点:
- 避免万向节死锁
-
四元数的缺点:
- 难于使用
- 存在不合法的四元数。
-
四元数要和欧拉角配合使用,相互互补。
-
通过代码访问当前物体的角度:
- 欧拉角:this.transform.eulerAngles
- 四元数:this.transform.rotation
-
四元数计算(四元数没有加减操作):
- 四元数 * 四元数 实现旋转效果的组合。
- 四元数 * 向量 实现向量旋转四元数大小的角度。此相乘必须为左乘。
5. 坐标系
unity坐标系为左手坐标系,四指指向z轴方向,向x轴弯曲,大拇指指向Y轴方向。
Unity坐标系:
World space:世界坐标系
- 整个场景的固定坐标。
- 作用:在游戏场景中表示每个游戏对象的位置和方向。
Local space:自身坐标系
- 每个物体的独立坐标系,随物体的移动或者旋转而改变。
- 用于表示物体间的相对位置和方向。
Screen space:屏幕坐标系:
- 以像素为单位,屏幕左下角为(0,0)点,右上角为(Screen.width,Screen.Height)。屏幕坐标系隐式保留了z轴以方便坐标系的转换。z轴表示到相机的距离。
- 用于表示物体在屏幕的位置。
Viewport space:视口坐标系:
- 左下角为(0,0)右上角为(1,1),和屏幕坐标系一样保留了z轴,z轴表示到相机的距离。
- 用于表示物体在相机中的位置。
坐标系转换:
Local --》World:
-
transform中提供的一些常量:
- transform.forward ==> rotation * Vector3.forward
- transform.right ==> rotation * Vector3.right
- transform.up ==> rotation * Vector3.up
- 会随着物体一起旋转,但如果想要跟随物体还需要加position
-
transform.TranformPoint(Vector3 vector):
- 转换点,受到物体位置,旋转,缩放影响(转换方向矢量请使用TransformDirection)。
-
transform.TransformDirection(Vector3 vector):
- 转换方向,只受物体旋转影响。
-
transform.TransformVector(Vector3 vector):
- 受物体旋转和缩放影响。
World --》Local:
- 在转世界坐标系的方法前面加Inverse
World --》Screen/ViewPoint:
- 相机引用.WorldToScreen[Viewpoint]Point(Vector3 vector);
Screen/ViewPoint --》World:
- 相机引用.Screen[Viewpoint]ToWorldPoint(Vector3 vector);