Unity Mathf 全方法示例详解(含每个方法可直接运行代码)

以下为 Mathf 常用方法的 独立可运行示例,每个方法都配具体场景代码(可直接复制到 Unity 脚本中测试),按功能分类,兼顾基础用法和实际开发场景,方便直接套用。

一、基础数值运算(直接运行验证结果)

1. Mathf.Abs(取绝对值)

void TestAbs()
{
    float negative = -7.8f;
    int intNegative = -10;
    float result1 = Mathf.Abs(negative);    // 结果:7.8
    int result2 = Mathf.Abs(intNegative);   // 结果:10
    Debug.Log($"Abs(-7.8f) = {result1}, Abs(-10) = {result2}");
}

场景:计算两点距离时(避免负数)、修正方向值等。

2. Mathf.Round(四舍五入取整)

void TestRound()
{
    float num1 = 3.4f;
    float num2 = 3.6f;
    int result1 = Mathf.RoundToInt(num1);   // 结果:3(RoundToInt 直接返回int)
    float result2 = Mathf.Round(num2);      // 结果:4.0f
    Debug.Log($"Round(3.4f) = {result1}, Round(3.6f) = {result2}");
}

场景:数值显示(如得分、数量)、简化浮点数为整数。

3. Mathf.Floor(向下取整)

void TestFloor()
{
    float num1 = 5.9f;
    float num2 = -2.1f;
    float result1 = Mathf.Floor(num1);      // 结果:5.0f(舍弃小数)
    float result2 = Mathf.Floor(num2);      // 结果:-3.0f(负数向下取整更负)
    Debug.Log($"Floor(5.9f) = {result1}, Floor(-2.1f) = {result2}");
}

场景:网格定位(如物体吸附到整数坐标)、分页计算(取当前页索引)。

4. Mathf.Ceil(向上取整)

void TestCeil()
{
    float num1 = 2.1f;
    float num2 = -3.8f;
    float result1 = Mathf.Ceil(num1);       // 结果:3.0f(小数非0进1)
    float result2 = Mathf.Ceil(num2);       // 结果:-3.0f(负数向上取整更接近0)
    Debug.Log($"Ceil(2.1f) = {result1}, Ceil(-3.8f) = {result2}");
}

场景:资源加载(如10.2个资源需加载11个)、容量计算(如5.1个物品需6个格子)。

5. Mathf.Max(取最大值)

void TestMax()
{
    float a = 2.3f, b = 5.7f, c = 3.0f;
    float maxSingle = Mathf.Max(a, b);      // 结果:5.7f(两个值比较)
    float maxMulti = Mathf.Max(a, b, c);    // 结果:5.7f(多个值比较)
    Debug.Log($"Max(2.3,5.7) = {maxSingle}, Max(2.3,5.7,3.0) = {maxMulti}");
}

场景:取角色最大血量、限制数值上限(配合其他方法)。

6. Mathf.Min(取最小值)

void TestMin()
{
    int x = 10, y = 5, z = 8;
    int minSingle = Mathf.Min(x, y);        // 结果:5(整数比较)
    int minMulti = Mathf.Min(x, y, z);      // 结果:5(多个整数比较)
    Debug.Log($"Min(10,5) = {minSingle}, Min(10,5,8) = {minMulti}");
}

场景:取角色最小伤害、限制数值下限。

7. Mathf.Pow(幂运算)

void TestPow()
{
    float square = Mathf.Pow(4, 2);         // 结果:16.0f(4的平方)
    float cube = Mathf.Pow(3, 3);           // 结果:27.0f(3的立方)
    float rootHalf = Mathf.Pow(4, 0.5f);    // 结果:2.0f(等同于平方根)
    Debug.Log($"4² = {square}, 3³ = {cube}, 4^0.5 = {rootHalf}");
}

场景:物理计算(如动能 = 0.5mv²)、数值缩放(如经验值随等级平方增长)。

8. Mathf.Sqrt(平方根)

void TestSqrt()
{
    float num = 25.0f;
    float root = Mathf.Sqrt(num);           // 结果:5.0f
    Debug.Log($"Sqrt(25) = {root}");
    
    // 实际场景:计算两点距离(简化版)
    float x1 = 1, y1 = 2;
    float x2 = 4, y2 = 6;
    float distance = Mathf.Sqrt(Mathf.Pow(x2 - x1, 2) + Mathf.Pow(y2 - y1, 2));
    Debug.Log($"两点距离:{distance}"); // 结果:5.0f
}

场景:距离计算、几何运算(如圆半径相关)。

9. Mathf.Repeat(循环数值,非负)

void TestRepeat()
{
    float t1 = 7.2f, length1 = 3;
    float t2 = -1.5f, length2 = 3;
    float result1 = Mathf.Repeat(t1, length1); // 结果:1.2f(7.2 - 2*3 = 1.2)
    float result2 = Mathf.Repeat(t2, length2); // 结果:1.5f(-1.5 + 3 = 1.5,始终非负)
    Debug.Log($"Repeat(7.2,3) = {result1}, Repeat(-1.5,3) = {result2}");
}

场景:循环动画帧索引(如0-9循环)、时间循环(如每5秒重复一次)。

10. Mathf.Sign(判断符号)

void TestSign()
{
    float num1 = -3.1f, num2 = 5.2f, num3 = 0;
    int sign1 = Mathf.Sign(num1);           // 结果:-1(负数)
    int sign2 = Mathf.Sign(num2);           // 结果:1(正数)
    int sign3 = Mathf.Sign(num3);           // 结果:0(零)
    Debug.Log($"Sign(-3.1) = {sign1}, Sign(5.2) = {sign2}, Sign(0) = {sign3}");
}

场景:判断角色移动方向(左右)、数值增减趋势。

二、三角函数与角度转换(Unity 三角函数默认弧度制)

1. Mathf.Deg2Rad(角度转弧度)

void TestDeg2Rad()
{
    float angleDeg = 180f; // 180度
    float angleRad = angleDeg * Mathf.Deg2Rad; // 结果:3.1416f(π弧度)
    Debug.Log($"180度 = {angleRad} 弧度");
}

场景:给三角函数传参前的单位转换。

2. Mathf.Rad2Deg(弧度转角度)

void TestRad2Deg()
{
    float angleRad = Mathf.PI / 2; // π/2 弧度
    float angleDeg = angleRad * Mathf.Rad2Deg; // 结果:90.0f(度)
    Debug.Log($"π/2 弧度 = {angleDeg} 度");
}

场景:三角函数计算结果转角度显示(如角色朝向角度)。

3. Mathf.Sin(正弦值)

void TestSin()
{
    float angle30 = 30f * Mathf.Deg2Rad;
    float sin30 = Mathf.Sin(angle30); // 结果:0.5f
    float angle90 = 90f * Mathf.Deg2Rad;
    float sin90 = Mathf.Sin(angle90); // 结果:1.0f
    Debug.Log($"Sin(30°) = {sin30}, Sin(90°) = {sin90}");
}

场景:周期性运动(如钟摆、波浪效果)、角度相关数值计算。

4. Mathf.Cos(余弦值)

void TestCos()
{
    float angle0 = 0f * Mathf.Deg2Rad;
    float cos0 = Mathf.Cos(angle0); // 结果:1.0f
    float angle180 = 180f * Mathf.Deg2Rad;
    float cos180 = Mathf.Cos(angle180); // 结果:-1.0f
    Debug.Log($"Cos(0°) = {cos0}, Cos(180°) = {cos180}");
}

场景:圆周运动(如物体绕原点旋转)、方向向量计算。

5. Mathf.Tan(正切值)

void TestTan()
{
    float angle45 = 45f * Mathf.Deg2Rad;
    float tan45 = Mathf.Tan(angle45); // 结果:1.0f
    float angle60 = 60f * Mathf.Deg2Rad;
    float tan60 = Mathf.Tan(angle60); // 结果:1.732f(√3)
    Debug.Log($"Tan(45°) = {tan45}, Tan(60°) = {tan60}");
}

场景:斜率计算、几何投影。

6. Mathf.Asin(反正弦值)

void TestAsin()
{
    float value = 1.0f;
    float angleRad = Mathf.Asin(value); // 结果:π/2 弧度(90度)
    float angleDeg = angleRad * Mathf.Rad2Deg;
    Debug.Log($"Asin(1.0) = {angleDeg} 度");
}

场景:通过正弦值反推角度(如已知对边和斜边求角度)。

7. Mathf.Acos(反余弦值)

void TestAcos()
{
    float value = 0f;
    float angleRad = Mathf.Acos(value); // 结果:π/2 弧度(90度)
    float angleDeg = angleRad * Mathf.Rad2Deg;
    Debug.Log($"Acos(0.0) = {angleDeg} 度");
}

场景:通过余弦值反推角度(如已知邻边和斜边求角度)。

8. Mathf.Atan(反正切值)

void TestAtan()
{
    float value = 1.0f;
    float angleRad = Mathf.Atan(value); // 结果:π/4 弧度(45度)
    float angleDeg = angleRad * Mathf.Rad2Deg;
    Debug.Log($"Atan(1.0) = {angleDeg} 度");
}

场景:简单角度反推(但无法判断象限)。

9. Mathf.Atan2(向量反正切值,推荐!)

void TestAtan2()
{
    // 第一象限向量(1,1)
    float angle1 = Mathf.Atan2(1, 1) * Mathf.Rad2Deg; // 结果:45度
    // 第三象限向量(-1,-1)
    float angle2 = Mathf.Atan2(-1, -1) * Mathf.Rad2Deg; // 结果:-135度(或225度)
    // 第二象限向量(-1,1)
    float angle3 = Mathf.Atan2(1, -1) * Mathf.Rad2Deg; // 结果:135度
    Debug.Log($"Atan2(1,1) = {angle1}°, Atan2(-1,-1) = {angle2}°, Atan2(1,-1) = {angle3}°");
}

场景:计算目标方向(如角色朝向鼠标位置)、向量角度判断(核心方法)。

三、数值限制与插值(动画/移动核心)

1. Mathf.Clamp(限制数值范围)

void TestClamp()
{
    float value1 = 15f, min = 0f, max = 10f;
    float clamped1 = Mathf.Clamp(value1, min, max); // 结果:10f(超出上限取上限)
    float value2 = -3f;
    float clamped2 = Mathf.Clamp(value2, min, max); // 结果:0f(超出下限取下限)
    Debug.Log($"Clamp(15,0,10) = {clamped1}, Clamp(-3,0,10) = {clamped2}");
}

场景:限制角色血量(0-100)、滑块数值、相机视角范围。

2. Mathf.Clamp01(限制0-1范围)

void TestClamp01()
{
    float value1 = 1.2f;
    float clamped1 = Mathf.Clamp01(value1); // 结果:1.0f
    float value2 = -0.5f;
    float clamped2 = Mathf.Clamp01(value2); // 结果:0.0f
    float value3 = 0.7f;
    float clamped3 = Mathf.Clamp01(value3); // 结果:0.7f(在范围内不变)
    Debug.Log($"Clamp01(1.2) = {clamped1}, Clamp01(-0.5) = {clamped2}, Clamp01(0.7) = {clamped3}");
}

场景:插值系数(t值)限制、进度条数值(0-1)、透明度(0-1)。

3. Mathf.Lerp(线性插值,渐变核心)

// 声明变量,需在Update中持续调用
private float currentValue = 2f;
private float targetValue = 5f;
private float speed = 1f;

void Update()
{
    TestLerp();
}

void TestLerp()
{
    // 每帧按速度更新插值,t = speed * Time.deltaTime(确保帧率无关)
    currentValue = Mathf.Lerp(currentValue, targetValue, speed * Time.deltaTime);
    Debug.Log($"Lerp渐变中:{currentValue:F2}"); // F2 保留2位小数
    // 接近目标时停止(避免无限循环)
    if (Mathf.Approximately(currentValue, targetValue))
    {
        Debug.Log($"Lerp完成,最终值:{currentValue}");
        enabled = false; // 关闭脚本
    }
}

场景:物体移动渐变、颜色渐变、数值平滑过渡(如音量调节)。

4. Mathf.LerpUnclamped(无限制线性插值)

void TestLerpUnclamped()
{
    float a = 2f, b = 5f;
    float t1 = 1.5f; // 超出1的t值
    float result1 = Mathf.LerpUnclamped(a, b, t1); // 结果:6.5f(2 + (5-2)*1.5)
    float t2 = -0.5f; // 小于0的t值
    float result2 = Mathf.LerpUnclamped(a, b, t2); // 结果:0.5f(2 + (5-2)*(-0.5))
    Debug.Log($"LerpUnclamped(2,5,1.5) = {result1}, LerpUnclamped(2,5,-0.5) = {result2}");
}

场景:超出目标范围的外推计算(如预测物体下一帧位置)。

5. Mathf.SmoothDamp(平滑阻尼,带减速效果)

// 声明变量,需在Update中持续调用
private float currentPos = 0f;
private float targetPos = 10f;
private float velocity = 0f; // 速度变量(引用类型,必须初始化)
private float smoothTime = 0.3f; // 平滑时间(越小越快)

void Update()
{
    TestSmoothDamp();
}

void TestSmoothDamp()
{
    // 平滑趋近目标,带自然减速
    currentPos = Mathf.SmoothDamp(currentPos, targetPos, ref velocity, smoothTime);
    Debug.Log($"SmoothDamp位置:{currentPos:F2},当前速度:{velocity:F2}");
    // 接近目标时停止
    if (Mathf.Approximately(currentPos, targetPos))
    {
        Debug.Log($"SmoothDamp完成,最终位置:{currentPos}");
        enabled = false;
    }
}

场景:相机跟随、UI元素平滑移动、数值缓冲(如血条平滑减少)。

6. Mathf.MoveTowards(匀速趋近,无减速)

// 声明变量,需在Update中持续调用
private float currentValue = 3f;
private float targetValue = 8f;
private float moveSpeed = 2f; // 每秒移动2个单位

void Update()
{
    TestMoveTowards();
}

void TestMoveTowards()
{
    // 匀速向目标移动,每次最大步长 = moveSpeed * Time.deltaTime
    currentValue = Mathf.MoveTowards(currentValue, targetValue, moveSpeed * Time.deltaTime);
    Debug.Log($"MoveTowards当前值:{currentValue:F2}");
    if (Mathf.Approximately(currentValue, targetValue))
    {
        Debug.Log($"MoveTowards完成,最终值:{currentValue}");
        enabled = false;
    }
}

场景:角色匀速移动、物体直线追击、数值匀速变化(如倒计时)。

7. Mathf.PingPong(往返循环,0→length→0)

void Update()
{
    TestPingPong();
}

void TestPingPong()
{
    float speed = 1f;
    float length = 5f; // 循环范围0-5
    // Time.time * speed 作为输入t,实现随时间往返
    float pingPongValue = Mathf.PingPong(Time.time * speed, length);
    Debug.Log($"PingPong往返值:{pingPongValue:F2}");
    // 实际场景:物体左右往返移动
    transform.position = new Vector3(pingPongValue, 0, 0);
}

场景:往返动画(如灯笼摇摆、平台往复移动)、呼吸灯效果(亮度0-1-0)。

四、实用工具(精度/随机/角度判断)

1. Mathf.Approximately(浮点数精度比较)

void TestApproximately()
{
    float a = 0.1f + 0.2f;
    float b = 0.3f;
    bool equalDirect = (a == b); // 结果:false(浮点数精度误差)
    bool equalApprox = Mathf.Approximately(a, b); // 结果:true(正确比较)
    Debug.Log($"直接比较(0.1+0.2==0.3):{equalDirect}");
    Debug.Log($"Approximately比较:{equalApprox}");
}

场景:所有浮点数比较场景(如判断是否到达目标值、数值相等判断)。

2. Mathf.PerlinNoise(平滑随机值)

void Update()
{
    TestPerlinNoise();
}

void TestPerlinNoise()
{
    // x轴随时间变化,y轴固定,生成平滑波动的随机值(0-1)
    float noiseX = Time.time * 0.5f;
    float noiseValue = Mathf.PerlinNoise(noiseX, 0f);
    Debug.Log($"PerlinNoise平滑随机值:{noiseValue:F2}");
    // 实际场景:物体上下浮动(y轴位置随噪声变化)
    transform.position = new Vector3(0, noiseValue * 2, 0); // 浮动范围0-2
}

场景:地形生成、自然特效(如火焰、水流波动)、随机但不突兀的数值变化。

3. Mathf.DeltaAngle(计算角度最短差值)

void TestDeltaAngle()
{
    float currentAngle = 350f;
    float targetAngle = 10f;
    // 350°到10°的最短路径是顺时针转20°,而非逆时针转340°
    float delta = Mathf.DeltaAngle(currentAngle, targetAngle);
    Debug.Log($"350°到10°的最短差值:{delta}°"); // 结果:20°
    
    float currentAngle2 = 90f;
    float targetAngle2 = 270f;
    // 90°到270°的最短路径是逆时针转180°(或顺时针180°,结果为-180°)
    float delta2 = Mathf.DeltaAngle(currentAngle2, targetAngle2);
    Debug.Log($"90°到270°的最短差值:{delta2}°"); // 结果:-180°
}

场景:角度插值(如角色转向目标时走最短路径)、旋转动画。

4. Mathf.InverseLerp(计算归一化比例)

void TestInverseLerp()
{
    float a = 2f, b = 8f;
    float value1 = 5f; // 在a和b之间
    float t1 = Mathf.InverseLerp(a, b, value1); // 结果:0.5f((5-2)/(8-2))
    float value2 = 10f; // 超出b
    float t2 = Mathf.InverseLerp(a, b, value2); // 结果:1.333f(外推)
    Debug.Log($"5在[2,8]中的比例:{t1:F2}");
    Debug.Log($"10在[2,8]中的比例:{t2:F2}");
    
    // 实际场景:进度条计算(如血量30/100 → 0.3比例)
    float currentHp = 30f, maxHp = 100f;
    float hpPercent = Mathf.InverseLerp(0, maxHp, currentHp);
    Debug.Log($"血量进度:{hpPercent:P0}"); // 结果:30%
}

场景:进度计算、数值归一化(如将任意范围值转为0-1比例)。

通用使用注意事项

  1. 所有方法均为静态,直接用 Mathf.方法名() 调用,无需实例化。
  2. 插值类方法(Lerp/SmoothDamp/MoveTowards)必须在 Update/FixedUpdate持续调用才会有渐变效果,单次调用仅返回当前插值结果。
  3. 浮点数精度:永远用 Mathf.Approximately(a, b) 代替 a == b,避免精度误差。
  4. 角度单位:三角函数(Sin/Cos/Atan等)仅接收弧度制,务必用 Deg2Rad/Rad2Deg 转换,否则结果会完全错误。
  5. 循环方法区别:Repeat 是单向循环(0→length→0),PingPong 是往返循环(0→length→0),根据需求选择。