Unity的Mathf
✅ 一、Mathf 核心定位 & 特性
1. 核心定义
Mathf 是 Unity 引擎内置原生的静态类,命名空间为 using UnityEngine;,无需安装任何包,创建Unity工程即可直接使用。
✅ 核心作用:处理 单个数值(int/float/双精度) 的数学运算、数值处理、三角函数、插值、常量调用等。
2. 核心特性
✅ 无需引入额外命名空间,开箱即用,Unity开发标配
✅ 所有方法/属性都是静态,直接 Mathf.XXX 调用即可
✅ 所有角度相关的API,全部基于【角度制】(0° ~ 360°),符合人类直观认知,无弧度转换坑
✅ 纯C#实现,兼容所有Unity开发模式(MonoBehaviour/UGUI/预制体等常规开发)
✅ 无GC分配,运算稳定,适合常规游戏开发的绝大多数单值运算场景
✅ 二、【重中之重】Mathf 与 Unity.Mathematics 的核心区别 & 分工
这是你连续问两个知识点的核心需求,必须彻底分清,否则开发必踩坑,这两个库没有优劣,只有分工不同,99%的Unity项目是两者配合使用的,整理了全网最清晰的对比表,建议收藏:
✅ 核心分工原则(一句话记住)
Mathf→ 处理【单个数值】的运算;Unity.Mathematics→ 处理【向量/矩阵/四元数】的批量运算
✅ 详细对比表(全维度,无遗漏)
| 对比维度 | Mathf (Unity原生) |
Unity.Mathematics (官方高性能库) |
|---|---|---|
| 处理对象 | ✅ 单个数值:int/float |
✅ 多维复合类型:float3/int2/quaternion/float4x4 |
| 角度制式 | ✅ 角度制 (90°、180°),无需转换 | ⚠️ 弧度制 (π/2、π),必须用math.radians(角度)转换 |
| 命名空间 | using UnityEngine;(唯一) |
using Unity.Mathematics; |
| 调用方式 | Mathf.方法名() |
类型构造+math.方法名() |
| 核心优势 | 1. 角度制无坑 2. 开箱即用 3. 单值运算简洁 4. 兼容所有场景 | 1. SIMD并行优化 2. Burst编译器深度适配 3. 向量矩阵运算极致快 4. DOTS生态标配 |
| 适用场景 | ✅ 所有常规开发:MonoBehaviour、UGUI、动画、逻辑判断、单值计算、协程等 | ✅ 高性能计算:ECS/JobSystem/Burst、粒子系统、海量坐标运算、物理模拟等 |
| GC情况 | 零GC,静态方法无分配 | 零GC,纯值类型无堆内存依赖 |
| 互补关系 | 两者可以无缝配合,比如:Mathf.PI 获取圆周率 → 传给 math.radians() 做转换 |
两者可以无缝配合,比如:math.length(float3) 得到向量长度 → 用 Mathf.Clamp() 限制范围 |
✅ 关键结论(开发必遵)
- 写常规逻辑(比如:血量限制、冷却时间计算、角度判断、单值插值)→ 无脑用
Mathf,简单高效无坑 - 写向量/旋转/矩阵(比如:坐标移动、朝向计算、模型旋转)→ 用
Unity.Mathematics的float3/quaternion - 写DOTS/Job/Burst → 必须用
Unity.Mathematics,禁止在Job中用Mathf - 两者完全兼容,可以混合调用,比如:
float3 dir = math.normalize(targetPos - selfPos); float angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg; // 向量运算用math,单值转换用Mathf
✅ 三、Mathf 核心常量(高频必背,使用率Top10)
所有常量都是 public static readonly,直接调用,无需计算,零性能损耗,是开发中最常用的内容,按使用频率排序:
// 圆周率相关(最常用)
Mathf.PI; // 圆周率 π ≈ 3.141592653589793
Mathf.Deg2Rad; // 角度 转 弧度 的系数 (π/180),比如 90 * Deg2Rad = π/2
Mathf.Rad2Deg; // 弧度 转 角度 的系数 (180/π),比如 π * Rad2Deg = 180°
// 数值相关
Mathf.Infinity; // 正无穷大 (常用于初始化最大值)
Mathf.NegativeInfinity; // 负无穷大
// 插值/平滑相关
Mathf.Epsilon; // 极小值(≈0),用于判断浮点数是否相等,比如 if(Mathf.Abs(a-b) < Epsilon)
✅ 四、Mathf 高频核心API(分大类整理,全覆盖99%开发场景)
所有API均为 public static,无需实例化,直接调用。我按开发使用频率优先级排序,加粗的是必记API,背会这些,开发中几乎不用查文档!
所有示例代码均可直接复制到Unity中运行,无依赖
✔ 1. 数值限制/裁剪 【使用率第一,必记】
处理数值边界,防止数值溢出(比如血量不能为负、音量0~1、移动速度限制)
// ✅ Mathf.Clamp(数值, 最小值, 最大值) → 强制把数值限制在[min,max]区间内,超了就取边界值
float hp = Mathf.Clamp(120, 0, 100); // hp = 100
float volume = Mathf.Clamp(-0.2f, 0, 1); // volume = 0
// ✅ Mathf.Clamp01(数值) → 等价 Clamp(数值,0,1),专门限制0~1区间,代码更简洁
float t = Mathf.Clamp01(1.5f); // t = 1
float alpha = Mathf.Clamp01(-0.3f); // alpha = 0
// Mathf.Max/Min 取多个值的最大/最小值
float maxVal = Mathf.Max(1,5,3,9); // maxVal =9
float minVal = Mathf.Min(0.2f, 0.5f, -0.1f); // minVal =-0.1f
✔ 2. 数值取整 【高频必用】
处理浮点数转整数的各种场景,注意区分四舍五入/向上/向下取整,这是高频坑点!
float num = 2.3f;
float num2 = 2.7f;
// ✅ Mathf.Round(数值) → 标准四舍五入
Mathf.Round(num); // 2
Mathf.Round(num2); // 3
// ✅ Mathf.Floor(数值) → 向下取整(地板),无论小数是多少,都舍弃
Mathf.Floor(num); // 2
Mathf.Floor(2.99f);// 2
// ✅ Mathf.Ceil(数值) → 向上取整(天花板),无论小数是多少,都进1
Mathf.Ceil(num); //3
Mathf.Ceil(2.01f); //3
// Mathf.RoundToInt → 四舍五入后直接返回int类型,省去强制转换
int val = Mathf.RoundToInt(2.5f); // val=3
✔ 3. 绝对值/符号值 【高频】
// ✅ Mathf.Abs(数值) → 取绝对值,负数变正数,正数不变
Mathf.Abs(-5); //5
Mathf.Abs(-3.2f);//3.2f
// ✅ Mathf.Sign(数值) → 获取数值的【符号】,返回值只有3种:1(正)、-1(负)、0(零)
Mathf.Sign(5); //1
Mathf.Sign(-3.2f);//-1
Mathf.Sign(0); //0
// 常用场景:判断移动方向、攻击方向
float moveDir = Mathf.Sign(Input.GetAxis("Horizontal"));
✔ 4. 插值运算 【核心API,必记,动画/平滑核心】
插值是游戏开发的灵魂,实现数值平滑过渡、动画缓动、属性渐变,Mathf的插值全部是单值插值,角度制无坑!
// ✅ Mathf.Lerp(起始值, 目标值, 插值系数t) → 线性插值,t∈[0,1]
// t=0 → 返回起始值;t=1 → 返回目标值;t=0.5 → 返回中间值,匀速过渡
float speed = Mathf.Lerp(0, 10, 0.5f); // speed=5
float posX = Mathf.Lerp(transform.position.x, 10, Time.deltaTime); // 平滑移动X轴到10
// ✅ Mathf.LerpAngle(起始角度, 目标角度, t) → 角度专用线性插值,自动处理360°循环(核心!)
// 比如:从350°插值到10°,会走最短路径(20°),而不是走340°,不会出现旋转卡顿
float angle = Mathf.LerpAngle(350, 10, 0.5f); // angle=0°
// Mathf.SmoothDamp → 平滑阻尼插值,带【惯性缓动】,比Lerp更丝滑,适合相机跟随、手感优化
float currentVel = 0;
float smoothPos = Mathf.SmoothDamp(transform.position.x, 10, ref currentVel, 0.2f);
✔ 5. 三角函数 【开发常用,无坑角度制】
Mathf的三角函数全部基于角度制,这是和 Unity.Mathematics 的核心区别,不用转换弧度,直接传角度即可,太香了!
// 正弦/余弦/正切,参数直接传【角度】
Mathf.Sin(0); // 0
Mathf.Sin(90); // 1
Mathf.Cos(0); // 1
Mathf.Cos(180); // -1
// ✅ Mathf.Atan2(y, x) → 极坐标反正切,返回【弧度值】,计算两个点的夹角必备!
// 通用公式:两点夹角 = Mathf.Atan2(y差, x差) * Mathf.Rad2Deg
Vector2 a = new Vector2(0,0);
Vector2 b = new Vector2(1,1);
float rad = Mathf.Atan2(b.y - a.y, b.x - a.x);
float angle = rad * Mathf.Rad2Deg; // angle=45°
✔ 6. 其他高频实用API
// ✅ Mathf.Pow(底数, 指数) → 幂运算,比如平方、立方
float square = Mathf.Pow(2,2); // 2²=4
float cube = Mathf.Pow(3,3); //3³=27
// ✅ Mathf.Sqrt(数值) → 平方根运算,比如向量长度计算的开方
float sqrt = Mathf.Sqrt(16); //4
// Mathf.DeltaAngle(当前角度, 目标角度) → 计算两个角度的【最短差值】,自动处理360°循环
// 比如:350°到10°的差值是20°,而不是-340°
float delta = Mathf.DeltaAngle(350, 10); // delta=20
✅ 五、Mathf 避坑指南(开发高频踩坑点,共3个,全部避开)
⚠️ 坑1:浮点数的「等于」判断,不能用 ==
Unity中float是浮点型,存在精度误差,比如 0.1+0.2 不等于 0.3,直接用==会得到错误结果。
✅ 正确写法:用 Mathf.Epsilon 判断两个数的差值是否小于极小值
float a = 0.1f + 0.2f;
float b = 0.3f;
// 错误:if(a == b) → false
// 正确:
if(Mathf.Abs(a - b) < Mathf.Epsilon)
{
Debug.Log("a和b相等"); // 会执行
}
⚠️ 坑2:Mathf.Lerp 的插值系数 t 必须手动限制在 [0,1]
Mathf.Lerp的t如果超过1,会继续插值导致数值溢出目标值,比如 Mathf.Lerp(0,10,2) 会返回20,不是10!
✅ 正确写法:配合 Mathf.Clamp01() 限制t的范围
float t = Time.deltaTime * 2; // t可能大于1
float val = Mathf.Lerp(0,10, Mathf.Clamp01(t)); // 永远不会超过10
⚠️ 坑3:旋转角度计算用 Mathf.LerpAngle 而不是 Mathf.Lerp
普通的Lerp处理角度时,不会处理360°循环,比如从350°到10°,会计算成 -340°,导致物体旋转一大圈而不是小角度。
✅ 正确写法:所有角度插值,一律用 Mathf.LerpAngle
✅ 六、Mathf 完整实用代码示例(常规开发高频场景)
这个示例整合了Mathf的核心API,模拟了游戏中最常见的逻辑场景,直接复制到MonoBehaviour脚本中即可运行,能帮你快速理解实际用法:
using UnityEngine;
public class MathfDemo : MonoBehaviour
{
public Transform target;
public float maxHp = 100;
private float currentHp = 100;
void Update()
{
// 1. 数值限制:扣血后血量不小于0
if (Input.GetKeyDown(KeyCode.Space))
{
currentHp -= 25;
currentHp = Mathf.Clamp(currentHp, 0, maxHp);
Debug.Log($"当前血量:{currentHp}");
}
// 2. 角度计算:看向目标的角度(无坑)
Vector3 dir = target.position - transform.position;
float angle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, angle, 0);
// 3. 平滑插值:相机平滑跟随目标X轴,带阻尼
float smoothX = Mathf.Lerp(transform.position.x, target.position.x, Time.deltaTime * 3);
transform.position = new Vector3(smoothX, transform.position.y, transform.position.z);
// 4. 绝对值判断:判断是否远离目标
float distance = Vector3.Distance(transform.position, target.position);
if (Mathf.Abs(distance) > 10)
{
Debug.Log("目标已远离,开始追击");
}
}
}
✅ 七、总结(核心知识点速记,必背)
Mathf是Unity原生静态数学类,处理单值运算,角度制无坑,开箱即用,常规开发首选。Mathf和Unity.Mathematics是互补关系,不是替代关系:单值用Mathf,向量矩阵用math库。- 必记3个核心常量:
Mathf.PI、Mathf.Deg2Rad、Mathf.Rad2Deg。 - 必记6个核心API:
Mathf.Clamp、Mathf.Clamp01、Mathf.Round、Mathf.Abs、Mathf.Lerp、Mathf.LerpAngle。 - 避坑三原则:浮点判断用Epsilon、Lerp的t要Clamp01、角度插值用LerpAngle。