Unity游戏开发中的3D数学基础详解
Unity游戏开发中的3D数学基础详解
掌握3D数学是游戏开发的核心技能之一,本文将全面解析Unity中的坐标系、向量运算、矩阵变换等关键数学概念
引言
在3D游戏开发中,数学是实现逼真视觉效果和流畅交互体验的基础。3D数学被广泛应用于图形学、虚拟现实和游戏开发领域,它帮助我们描述和操作3D空间中的对象。Unity作为主流的游戏开发引擎,其内部实现大量依赖3D数学原理。本文将系统讲解Unity游戏开发所需的3D数学基础知识。
第一章:3D数学基础概念
1.1 坐标系系统
1D坐标系:
- 表示在一条直线上的位置
- 包含原点、方向和单位长度
- 如数轴:
--|----|----|---->
-3 -2 -1 0 1 2 3
2D笛卡尔坐标系:
- 由两条互相垂直的数轴组成
- 点用(x,y)表示
- 示例:(4,3)表示x轴4单位,y轴3单位的位置
// Unity中获取2D位置
Vector2 position = new Vector2(4, 3);
3D空间直角坐标系:
- 包含三个互相垂直的轴(X,Y,Z)
- 点用(x,y,z)表示
- 三个坐标平面:XY、XZ、YZ平面
1.2 左手坐标系与右手坐标系
特征 | 左手坐标系 | 右手坐标系 |
---|---|---|
确定方法 | 左手:拇指=X,食指=Y,中指=Z | 右手:拇指=X,食指=Y,中指=Z |
使用引擎 | Unity、Direct3D | OpenGL、3D笛卡尔坐标系 |
Z轴方向 | 指向屏幕内部 | 指向屏幕外部 |
Unity的坐标系:
- 世界坐标系:左手系
- +X:右方
- +Y:上方
- +Z:前方
第二章:Unity中的坐标系系统
2.1 坐标系类型
全局坐标系(世界坐标系):
- 场景中所有物体的位置基准
- 获取方式:
transform.position
局部坐标系(物体坐标系):
- 每个物体独立的坐标系
- 随物体移动/旋转而变化
- 获取方式:
transform.localPosition
// 获取Cube在世界坐标和局部坐标中的位置
Vector3 worldPos = transform.position;
Vector3 localPos = transform.localPosition;
屏幕坐标系:
- 基于屏幕的2D坐标系
- 左下角(0,0),右上角(Screen.width, Screen.height)
- 获取鼠标位置:
Input.mousePosition
视口坐标系:
- 单位化屏幕坐标系
- 左下角(0,0),右上角(1,1)
2.2 坐标系转换
全局坐标与局部坐标转换
// 局部坐标转世界坐标
Vector3 worldPoint = transform.TransformPoint(localPoint);// 世界坐标转局部坐标
Vector3 localPoint = transform.InverseTransformPoint(worldPoint);
世界坐标与屏幕坐标转换
// 世界坐标转屏幕坐标
Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);// 屏幕坐标转世界坐标
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
坐标系转换关系图
全局坐标系 ⇄ 局部坐标系⇅ ⇅
屏幕坐标系 ⇄ 视口坐标系
第三章:向量的基本概念
3.1 向量与点的区别
特性 | 点(Point) | 向量(Vector) |
---|---|---|
含义 | 表示位置 | 表示方向和大小 |
位移 | 无 | 有方向和大小的位移 |
Unity表示 | Vector3 | Vector3 |
示例 | transform.position | transform.forward |
3.2 向量的基本操作
// 创建点和向量
Vector3 pointA = new Vector3(1, 2, 3); // 点
Vector3 direction = new Vector3(0, 1, 0); // 向量// 计算两点间距离
float distance = Vector3.Distance(pointA, pointB);// 等价计算方式
float distance = (pointB - pointA).magnitude;
第四章:向量运算
4.1 基本运算
零向量:Vector3.zero
→ (0,0,0)
负向量:对每个分量取反
Vector3 original = new Vector3(2, -3, 3);
Vector3 negative = -original; // (-2, 3, -3)
向量长度:
Vector3 v = new Vector3(1, 2, 3);
float length = v.magnitude; // 长度
float sqrLength = v.sqrMagnitude; // 长度的平方(性能更优)
4.2 向量运算
标量乘法:
Vector3 v = new Vector3(1, 2, 3);
Vector3 scaled = v * 2; // (2, 4, 6)
单位向量(归一化):
Vector3 v = new Vector3(4, 3, 0);
Vector3 unit = v.normalized; // (0.8, 0.6, 0)// 手动归一化
Vector3 manualUnit = v / v.magnitude;
加减法:
Vector3 a = new Vector3(1, 3, 0);
Vector3 b = new Vector3(2, 5, 0);
Vector3 sum = a + b; // (3, 8, 0)
Vector3 diff = a - b; // (-1, -2, 0)
4.3 点积与叉积
点积(Dot Product):
- 公式:a·b = |a||b|cosθ
- 几何意义:投影长度、夹角关系
- Unity实现:
Vector3.Dot(a, b)
Vector3 a = new Vector3(0, 2, 0);
Vector3 b = new Vector3(3, 3, 0);
float dot = Vector3.Dot(a, b); // 6// 计算夹角
float angle = Vector3.Angle(a, b); // 45度
点积的几何意义:
-
0:锐角(0°-90°)
- =0:直角(90°)
- <0:钝角(90°-180°)
叉积(Cross Product):
- 仅适用于3D向量
- 结果是一个垂直于原向量的新向量
- Unity实现:
Vector3.Cross(a, b)
Vector3 a = new Vector3(1, 2, 3);
Vector3 b = new Vector3(-2, -2, 3);
Vector3 cross = Vector3.Cross(a, b); // (12, -9, 2)
叉积的应用:
- 计算平面法线
- 判断物体相对方向(顺时针/逆时针)
- 计算平行四边形面积
第五章:矩阵与变换
5.1 矩阵基础
矩阵定义:
- r×c矩阵:r行c列的数字阵列
- Unity中的矩阵:
Matrix4x4
(4×4矩阵)
// 创建单位矩阵
Matrix4x4 identity = Matrix4x4.identity;// 设置矩阵行
Matrix4x4 matrix = new Matrix4x4();
matrix.SetRow(0, new Vector4(1,0,0,0));
5.2 特殊矩阵
矩阵类型 | 特性 | Unity实现 |
---|---|---|
单位矩阵 | 对角元素为1,其余为0 | Matrix4x4.identity |
零矩阵 | 所有元素为0 | Matrix4x4.zero |
转置矩阵 | 行列互换 | Matrix4x4.transpose |
逆矩阵 | AA⁻¹=I | Matrix4x4.inverse |
5.3 矩阵运算
矩阵乘法:
Matrix4x4 a = new Matrix4x4();
Matrix4x4 b = new Matrix4x4();
Matrix4x4 result = a * b;// 矩阵与向量相乘
Vector3 point = new Vector3(1, 2, 3);
Vector3 transformed = matrix.MultiplyPoint(point);
第六章:3D变换
6.1 齐次坐标
为什么需要齐次坐标:
- 统一表示点和向量
- 方便进行仿射变换(线性变换+平移)
表示方式:
- 点:(x,y,z,1)
- 向量:(x,y,z,0)
6.2 基本变换矩阵
平移矩阵:
| 1 0 0 tx |
| 0 1 0 ty |
| 0 0 1 tz |
| 0 0 0 1 |
缩放矩阵:
| sx 0 0 0 |
| 0 sy 0 0 |
| 0 0 sz 0 |
| 0 0 0 1 |
旋转矩阵(绕Y轴):
| cosθ 0 sinθ 0 |
| 0 1 0 0 |
| -sinθ 0 cosθ 0 |
| 0 0 0 1 |
6.3 Unity中的变换实现
// 创建变换矩阵
Matrix4x4 translation = Matrix4x4.Translate(new Vector3(1,2,3));
Matrix4x4 rotation = Matrix4x4.Rotate(Quaternion.Euler(0,45,0));
Matrix4x4 scale = Matrix4x4.Scale(new Vector3(2,2,2));// 复合变换矩阵(注意顺序:缩放->旋转->平移)
Matrix4x4 composite = translation * rotation * scale;// 应用变换
Vector3 original = new Vector3(1,0,0);
Vector3 transformed = composite.MultiplyPoint(original);
变换顺序的重要性:
- 矩阵乘法不满足交换律
- 推荐顺序:缩放 → 旋转 → 平移
- 不同顺序产生不同结果
6.4 习题答案
问题:实现游戏物体匀速移动到目标位置
public Transform target;
public float speed = 2.0f;void Update() {// 计算移动方向Vector3 direction = (target.position - transform.position).normalized;// 计算移动距离float step = speed * Time.deltaTime;// 移动物体transform.position += direction * step;
}