Unity基础-Mathf相关
Unity基础-Mathf相关
一、Mathf数学工具
概述
Mathf是Unity中封装好用于数学计算的工具结构体,提供了丰富的数学计算方法,特别适用于游戏开发场景。它是Unity开发中最常用的数学工具之一,能够帮助我们处理各种数学计算和插值运算。
Mathf与Math的区别
- Math是C#中封装好用于数学计算的工具类——位于System命名空间下
- Mathf是Unity中封装好用于数学计算的工具结构体
- 二者相关方法几乎一样
- Math是C#自带的工具类,主要提供有关数学的方法
- Mathf是Unity专门封装的,包含Math的相关方法,还有适用游戏开发的相关方法
Mathf常用方法
1. 计算一次的方法
// 1. 圆周率PI
print(Mathf.PI); // 输出3.141593// 2. 绝对值Abs
print(Mathf.Abs(-10)); // 输出10// 3. 向上取整CeilToInt
print(Mathf.CeilToInt(1.1f)); // 输出2// 4. 向下取整FloorToInt
print(Mathf.FloorToInt(1.9f)); // 输出1// 5. 钳制函数Clamp
print(Mathf.Clamp(10, 0, 5)); // 输出5
print(Mathf.Clamp(20, 0, 25)); // 输出25
print(Mathf.Clamp(-1, 0, 25)); // 输出0// 6. 最大值Max
print(Mathf.Max(1, 2)); // 输出2// 7. 最小值Min
print(Mathf.Min(1, 2)); // 输出1// 8. 幂运算Pow
print(Mathf.Pow(2, 3)); // 输出8// 9. 四舍五入RoundToInt
print(Mathf.RoundToInt(1.5f)); // 输出2// 10. 平方根Sqrt
print(Mathf.Sqrt(4)); // 输出2// 11. 是否为2的幂IsPowerOfTwo
print(Mathf.IsPowerOfTwo(4)); // 输出true// 12. 判断正负Sign
print(Mathf.Sign(1)); // 输出1
总结:这些基础数学方法在游戏开发中经常使用,特别是在处理数值计算、位置计算和游戏逻辑时。它们提供了精确的数学运算,帮助我们实现各种游戏功能。
2. 计算多次的方法
线性插值Lerp
线性插值是游戏开发中最常用的数学工具之一,它能够实现平滑的过渡效果,使游戏画面更加自然流畅。
// 用于两个值之间的差值过渡Mathf.Lerp(初始值,目标值,插值系数)
// 差值系数取值范围[0,1]
// 计算公式:result = start + (end - start) * t
print(Mathf.Lerp(1, 10, 0.5f)); // 输出5.5// 差值运算用法一
// 每帧更新start的值 变化速度先快后慢,位置无限接近end,但是不会得到end
start = Mathf.Lerp(start, end, Time.deltaTime);// 差值运算用法二
// 每帧更新time的值,变化速度匀速,位置每帧接近,当time=1时,result=end
float time = 0;
time += Time.deltaTime;
result = Mathf.Lerp(start, end, time);
扩展知识:
- Lerp不仅可以用于位置插值,还可以用于:
- 颜色渐变
- 旋转角度
- 缩放大小
- 透明度变化
- 除了线性插值,Unity还提供了其他插值方法:
- Vector3.Lerp:向量插值
- Quaternion.Lerp:四元数插值
- Color.Lerp:颜色插值
Lerp实际应用示例
下面通过一个具体的示例来展示Lerp在游戏开发中的实际应用,这个示例展示了两种不同的移动实现方式。
public class MathfTest : MonoBehaviour
{public Transform cube;private Vector3 start;private float speed=1;private float time=0;private Vector3 startPos;private Vector3 bPos;// Start is called before the first frame updatevoid Start(){start=this.transform.position;}// Update is called once per framevoid Update(){// Move1();// Move2();}private void Move1(){//方法1 先快后慢start.x=Mathf.Lerp(start.x,cube.position.x,speed*Time.deltaTime);start.y=Mathf.Lerp(start.y,cube.position.y,speed*Time.deltaTime);start.z=Mathf.Lerp(start.z,cube.position.z,speed*Time.deltaTime);this.transform.position=start;//使用Vector3.Lerp方法// transform.position=Vector3.Lerp(transform.position,cube.position,speed*Time.deltaTime);}private void Move2(){//方法2 匀速time+=Time.deltaTime;if(bPos!=cube.position){time=0;bPos=cube.position;startPos=transform.position;}start.x=Mathf.Lerp(startPos.x,bPos.x,time);start.y=Mathf.Lerp(startPos.y,bPos.y,time);start.z=Mathf.Lerp(startPos.z,bPos.z,time);transform.position=start;}
}
两种移动方式的区别:
-
方法1(先快后慢):
- 使用Time.deltaTime作为插值系数
- 移动速度随着距离目标越近而越慢
- 永远不会完全到达目标位置
- 适合相机跟随等场景
-
方法2(匀速移动):
- 使用time变量作为插值系数
- 移动速度保持恒定
- 可以完全到达目标位置
- 适合需要精确控制的场景
使用建议:
- 选择移动方式时需要考虑:
- 是否需要精确控制移动时间
- 是否需要完全到达目标位置
- 移动效果的自然程度要求
- 可以结合两种方法的特点:
- 使用方法1实现平滑的相机跟随
- 使用方法2实现精确的物体移动
应用场景
Mathf在游戏开发中的应用非常广泛,主要包括:
-
游戏对象移动和旋转
- 角色移动
- 相机跟随
- 物体旋转
-
平滑动画过渡
- UI动画
- 场景切换
- 特效渐变
-
物理计算和碰撞检测
- 碰撞检测
- 物理模拟
- 力的计算
-
游戏逻辑中的数学运算
- 伤害计算
- 属性计算
- 随机数生成
扩展应用:
-
游戏AI
- 寻路算法
- 行为决策
- 状态转换
-
特效系统
- 粒子效果
- 光照变化
- 材质过渡
-
UI系统
- 界面动画
- 进度条
- 数值显示