当前位置: 首页 > news >正文

Untiy入门学习(一)3D数学(1)之数学计算公共类Mathf

目录

一、Unity Mathf 类的主要方法和属性

1、常用静态属性

2、重要静态方法

 基础数学工具方法

取整与舍入方法

极值与数值逼近

 周期与噪声生成

柏林噪声 vs 随机数

插值与平滑:

(1)Mathf.Lerp(线性插值)

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

(3)Mathf.SmoothStep(平滑过渡)

作用:生成一个 S 形平滑曲线过渡,起始和结束时的速度较慢,中间较快,适合自然缓动效果。

示例:平滑开门动画

(4)Mathf.SmoothDamp(阻尼平滑过渡)

总结与对比

数值限制与映射

(1) Mathf.Clamp(float value, float min, float max)功能

示例:限制玩家血量

示例:UI 渐入渐出效果

示例:循环移动平台,一直往指定方向移动直到到达后返回起点

示例:动态进度条

扩展用法:反向映射非连续区间

对比总结

三角函数与角度处理

其他实用方法

二、Mathf 与 C# Math 类的区别

三、总结

Unity Mathf 类完整总结

1、常用静态属性

2、基础数学工具方法

3、取整与舍入方法

4、极值与数值逼近

5、周期与噪声生成

6、插值与平滑

7、数值限制与映射

8、其他实用方法

9、Mathf 与 C# Math 的对比

10、三角函数与角度处理


一、Unity Mathf 类的主要方法和属性


1、常用静态属性


        Mathf.Deg2Rad 和 Mathf.Rad2Deg
用于角度与弧度的转换。Deg2Rad = π/180,Rad2Deg = 180/π。
示例:将角度转为弧度 float radians = 90 * Mathf.Deg2Rad;
        Mathf.Epsilon
一个极小的浮点数值(约 1e-45),用于避免浮点数精度误差的比较操作。
        Mathf.Infinity 和 Mathf.NegativeInfinity
表示正负无穷大的常量,常用于范围判断(如射线检测的无限制距离)。
        Mathf.PI
表示圆周率 π 的浮点数值(精度为 float)。

2、重要静态方法

 基础数学工具方法

(1)Mathf.Abs(float value)
功能:返回绝对值(忽略正负号)。
(2)Mathf.Sign(float value)
功能:返回数值的符号(1 表示正数,-1 表示负数,0 表示零)。
(3)Mathf.Sqrt(float value)
功能:计算平方根。
注意:若 value < 0,返回 NaN(非数字)。

取整与舍入方法

(1)Mathf.Ceil(float value)
功能:向上取整(返回大于等于 value 的最小整数,类型为 float)。
float ceilResult = Mathf.Ceil(3.2f); // 返回 4.0f

(2) Mathf.Floor(float value)
功能:向下取整(返回小于等于 value 的最大整数,类型为 float)。
float floorResult = Mathf.Floor(3.8f); // 返回 3.0f

(3)Mathf.Round(float value)
功能:四舍五入(使用“银行家舍入法”:当 value 恰好在两个整数中间时,舍入到最近的偶数)
float round1 = Mathf.Round(2.5f); // 返回 2.0f(中间值舍入到偶数)
float round2 = Mathf.Round(3.5f); // 返回 4.0f

(4)Mathf.CeilToInt (向上取整)与 Mathf.FloorToInt(向下取整)
功能:直接返回 int 类型的取整结果。
int ceilInt = Mathf.CeilToInt(3.2f); // 返回 4
int floorInt = Mathf.FloorToInt(3.8f); // 返回 3

极值与数值逼近

(1)Mathf.Max 和 Mathf.Min
功能:返回多个数值中的最大或最小值。
重载:支持 float、int 及参数列表(如 Mathf.Max(1, 2, 3))。

示例:

float maxDamage = Mathf.Max(baseDamage, criticalDamage); // 取伤害最大值
float minSpeed = Mathf.Min(currentSpeed, maxSpeedLimit); // 限制最低速度

(2)Mathf.MoveTowards(float current, float target, float maxDelta)
功能:以固定步长 maxDelta 从 current 向 target 移动,避免超出目标值。
与 Lerp 的区别:Lerp 按比例插值,MoveTowards 按固定速度逼近。
public float speed = 5.0f;
void Update() {transform.position = Vector3.MoveTowards(transform.position,target.position,speed * Time.deltaTime);
}

 周期与噪声生成

(1)Mathf.PingPong(float t, float length)
功能:在 [0, length] 区间内往返循环数值(类似乒乓球运动)。
公式:PingPong(t, length) = length - Mathf.Abs(Repeat(t, 2 * length) - length)

示例(物体往返移动):

void Update() {float x = Mathf.PingPong(Time.time * 2, 10); // 在 0~10 之间往返transform.position = new Vector3(x, 0, 0);
}

(2)Mathf.PerlinNoise(float x, float y)

         是 Unity 中用于生成柏林噪声(Perlin Noise)的核心方法。柏林噪声是一种自然、连续的随机噪声算法,广泛用于程序化生成地形、纹理、云层、火焰等自然效果。与普通随机数不同,柏林噪声具有以下特点:

柏林噪声的核心特性
连续性:噪声值在相邻点之间平滑过渡,没有突变。
自然性:生成的图案类似自然界中的地形或云层。
可重复性:相同输入坐标 (x, y) 永远返回相同的噪声值。


功能:生成柏林噪声值(范围 [0,1]),用于自然随机效果(地形、纹理等)。
参数:输入坐标 x 和 y,建议使用连续的小幅增量(如 0.1f)。

示例(生成地形高度):

public int width = 100;
public int height = 100;
public float scale = 20f;void GenerateTerrain() {for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {float xCoord = (float)x / width * scale;float yCoord = (float)y / height * scale;float heightValue = Mathf.PerlinNoise(xCoord, yCoord);// 根据 heightValue 设置地形高度}}
}

柏林噪声 vs 随机数

特性柏林噪声随机数 (Random.Range)
连续性相邻值平滑过渡完全随机,无连续性
自然性适合模拟自然现象(地形、云层)适合离散事件(暴击率、掉落)
性能计算成本较高计算成本极低

插值与平滑:

(1)Mathf.Lerp(线性插值)

作用:在 a 和 b 之间按比例 t 进行线性插值。当 t ∈ [0,1] 时,结果在 [a, b] 范围内;t=0 返回 a,t=1 返回 b。

基本原理:Lerp(a, b, t) = a + (b - a) * t

例如该函数实现一个物体的颜色渐变:

public class ColorLerp : MonoBehaviour
{public Color startColor = Color.red;public Color endColor = Color.blue;public float duration = 3.0f;private float t = 0;void Update(){t += Time.deltaTime / duration;// 使用 Lerp 插值颜色GetComponent<Renderer>().material.color = Color.Lerp(startColor, endColor, t);}
}

        注意:Lerp 的 t 通常需要随时间递增,但直接使用 Time.deltaTime 可能导致动画不完成(需确保 t 最终达到 1)。

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

作用:允许 t 超出 [0,1],实现外插值。当 t < 0 或 t > 1 时,结果会超出 a 和 b 的范围。

示例:超出范围的移动

public class MoveBeyond : MonoBehaviour
{public Transform startPoint;public Transform endPoint;public float speed = 0.5f;private float t = 0;void Update(){t += Time.deltaTime * speed;// t 可能超过 1,物体会移动到终点之后transform.position = Vector3.LerpUnclamped(startPoint.position, endPoint.position, t);}
}
(3)Mathf.SmoothStep(平滑过渡)
作用:生成一个 S 形平滑曲线过渡,起始和结束时的速度较慢,中间较快,适合自然缓动效果。

SmoothStep(a, b, t) = a + (b - a) * (t² * (3 - 2t))

示例:平滑开门动画
public class DoorController : MonoBehaviour
{public float openAngle = 90f;public float smoothTime = 2.0f;private float currentAngle = 0;private float t = 0;void Update(){t += Time.deltaTime / smoothTime;// 使用 SmoothStep 实现平滑旋转currentAngle = Mathf.SmoothStep(0, openAngle, t);transform.rotation = Quaternion.Euler(0, currentAngle, 0);}
}
(4)Mathf.SmoothDamp(阻尼平滑过渡)

作用:模拟阻尼运动,逐渐逼近目标值,适合相机跟随、物体缓动停止等场景。它会自动计算平滑速度,避免突然停止。

参数
current:当前值
target:目标值
currentVelocity:当前速度(需声明为引用参数 ref)
smoothTime:过渡时间(秒)
maxSpeed(可选):最大限制速度

例如:相机平滑跟随玩家

public class CameraFollow : MonoBehaviour
{public Transform target;public float smoothTime = 0.3f;private Vector3 velocity = Vector3.zero;void LateUpdate(){Vector3 targetPosition = target.position + new Vector3(0, 5, -10);// 使用 SmoothDamp 实现平滑跟随transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);}
}

velocity 需声明为类成员变量以保持连续性。
smoothTime 越小,跟随速度越快。
maxSpeed 可防止高速移动时抖动。

总结与对比
方法特点适用场景
Lerp线性匀速过渡颜色渐变、简单位置移动
LerpUnclamped允许超出起点和终点弹道轨迹、快速掠过动画
SmoothStepS 形曲线,缓入缓出平滑的 UI 动画、旋转效果
SmoothDamp阻尼运动,自动计算速度,避免抖动相机跟随、物体缓动停止

 注意:上面举的示例只是因为,有明显效果,才使用的其他类里面的相关插值函数。实际上,这些插值函数都是依赖于Mathf的。

数值限制与映射

        在 Unity 的 Mathf 类中,ClampClamp01Repeat 和 InverseLerp 是用于数值限制、循环和区间映射的核心工具。

(1) Mathf.Clamp(float value, float min, float max)
功能

将 value 限制在 [min, max] 区间内。
如果 value < min,返回 min。
如果 value > max,返回 max。
如果 min > max,Unity 会自动交换 min 和 max,确保逻辑正确。

参数

value:需要限制的原始值。
min:区间下限。
max:区间上限。

示例:限制玩家血量
public class PlayerHealth : MonoBehaviour
{public float currentHealth = 50f;public float maxHealth = 100f;public float minHealth = 0f;void TakeDamage(float damage){currentHealth -= damage;currentHealth = Mathf.Clamp(currentHealth, minHealth, maxHealth);Debug.Log("当前血量:" + currentHealth);}void Heal(float amount){currentHealth += amount;currentHealth = Mathf.Clamp(currentHealth, minHealth, maxHealth);Debug.Log("当前血量:" + currentHealth);}
}
(2)Mathf.Clamp01(float value) 

功能
将 value 限制在 [0, 1] 区间。等价于 Clamp(value, 0, 1)。

使用场景
颜色透明度(Alpha)、进度比例、归一化参数。

示例:UI 渐入渐出效果
public class UIFade : MonoBehaviour
{public CanvasGroup uiGroup;public float fadeSpeed = 0.5f;private float targetAlpha = 0f;void Update(){// 按下空格键切换显隐if (Input.GetKeyDown(KeyCode.Space))targetAlpha = (targetAlpha == 0) ? 1 : 0;// 平滑过渡透明度uiGroup.alpha = Mathf.Lerp(uiGroup.alpha, targetAlpha, Time.deltaTime * fadeSpeed);// 确保透明度在 [0,1] 范围内uiGroup.alpha = Mathf.Clamp01(uiGroup.alpha);}
}
(3)Mathf.Repeat(float t, float length)

功能
将数值 t 循环限制在 [0, length) 区间(左闭右开)。
当 t 超过 length 时,会从 0 重新开始。
支持负数:Repeat(-1, 5) 返回 4。

Repeat(t, length) = t - length * floor(t / length)

示例:循环移动平台,一直往指定方向移动直到到达后返回起点
public class MovingPlatform : MonoBehaviour
{public float speed = 1f;public float moveDistance = 5f;private Vector3 startPos;void Start(){startPos = transform.position;}void Update(){// 计算循环时间(周期为 moveDistance/speed 秒)float t = Time.time * speed;float x = Mathf.Repeat(t, moveDistance);// 平台在 startPos.x 到 startPos.x + moveDistance 之间来回移动transform.position = startPos + new Vector3(x, 0, 0);}
}
(4)Mathf.InverseLerp(float a, float b, float value)

功能
计算 value 在 [a, b] 区间中的归一化比例位置。
如果 value <= a,返回 0。
如果 value >= b,返回 1。
如果 a = b,返回 0(避免除以零错误)。

InverseLerp(a, b, value) = (value - a) / (b - a)

示例:动态进度条
public class ProgressBar : MonoBehaviour
{public Transform loadingBar;public float minValue = 0f;public float maxValue = 100f;public float currentValue = 30f;void Update(){// 计算进度比例(0~1)float progress = Mathf.InverseLerp(minValue, maxValue, currentValue);// 应用进度到UI(假设进度条Scale从0到1)loadingBar.localScale = new Vector3(progress, 1, 1);}
}
扩展用法:反向映射非连续区间
// 将 [-10, 10] 映射到 [0, 1]
float t = Mathf.InverseLerp(-10, 10, temperature);
// 如果 temperature = 5,则 t = 0.75

对比总结

方法核心功能典型场景返回值范围
Clamp硬性限制数值范围血量、冷却时间[min, max]
Clamp01限制数值到 0~1透明度、归一化参数[0, 1]
Repeat循环数值周期性动画、计时器[0, length)
InverseLerp计算数值在区间中的比例位置进度条、动态插值参数[0, 1](可超出)

三角函数与角度处理

Sin、Cos、Tan这些我们后面会专门单独学习这个
接受弧度参数,与 Math 类一致。
DeltaAngle(float current, float target)
计算两个角度间的最小差值(考虑360°循环)。

其他实用方法

(1)Mathf.Approximately(float a, float b)
功能:判断两个浮点数是否近似相等(避免精度误差)。
if (Mathf.Approximately(playerHealth, 0)) {// 玩家生命值接近0时触发死亡
}

(2)Mathf.NextPowerOfTwo(int value)
功能:返回大于等于 value 的最小 2 的幂次数(如 7 → 8,9 → 16)。
(3)Mathf.ClosestPowerOfTwo(int value)
功能:返回最接近 value 的 2 的幂次数(如 7 → 8,15 → 16)。
(4)Mathf.Pow(float powerBase, float exponent)
作用:计算一个数的 n 次幂(即 powerBase^exponent)。

参数:
powerBase:底数(基数)。
exponent:指数(幂)。
返回值类型:float。

// 计算 2 的 3 次方(2^3 = 8)
float result = Mathf.Pow(2, 3); // 返回 8.0f
print(result); // 输出 8

注意:
如果 exponent 为负数,结果为 1 / (base^|exponent|)(例如 Pow(2, -3) → 0.125f)。
当 powerBase 为负数且 exponent 为非整数时,返回 NaN(如 Pow(-2, 0.5f))。 

(5)Mathf.IsPowerOfTwo(int value)
作用:判断一个整数是否是 2 的幂次方(如 1, 2, 4, 8, 16...)。
参数:value:需要判断的整数。
返回值类型:bool。
bool isPowerOfTwo1 = Mathf.IsPowerOfTwo(4);  // true(4 = 2^2)
bool isPowerOfTwo2 = Mathf.IsPowerOfTwo(3);  // false
bool isPowerOfTwo3 = Mathf.IsPowerOfTwo(0);  // false(0 不是 2 的幂次)
print(isPowerOfTwo1); // 输出 True

二、Mathf 与 C# Math 类的区别

1. 数据类型与精度


Mathf 针对 float 类型优化,适合Unity引擎中大量使用的单精度浮点数运算。
Math 类(位于 System 命名空间)默认使用 double 类型,精度更高但性能开销略大。

2. 功能扩展 游戏开发专用方法


Mathf 提供了 Lerp、SmoothDamp、DeltaAngle 等方法,专为游戏动画、物理模拟设计,而 Math 类缺少这些功能。
角度转换常量
Mathf.Deg2Rad 和 Mathf.Rad2Deg 简化了角度与弧度的转换,而使用 Math 类需手动计算(如 Math.PI / 180)。

3. 方法实现差异


Clamp 方法的存在性
在较新的C#版本中,Math 类可能支持 Clamp,但Unity的传统Mono版本可能依赖 Mathf 的实现。
Math.PI vs Mathf.PI
Math.PI 是 double 类型(更高精度),而 Mathf.PI 是 float 类型。

小结:Mathf 类 是Unity游戏开发的首选工具,提供高效且针对性的数学方法,适合处理浮点数运算、动画插值、角度转换等常见需求。
C# Math 类 更适用于通用编程和高精度计算,但在Unity中可能因类型转换和功能缺失不如 Mathf 便捷。

三、总结

Unity Mathf 类完整总结


1、常用静态属性

属性名作用值/公式返回值类型示例
Mathf.Deg2Rad角度转弧度系数π/180float90 * Deg2Rad → 1.5708f (π/2)
Mathf.Rad2Deg弧度转角度系数180/πfloatMathf.PI * Rad2Deg → 180
Mathf.Epsilon极小的浮点数值(避免精度误差)≈1e-45floatif (a - b < Epsilon)
Mathf.Infinity正无穷大float.PositiveInfinityfloatPhysics.Raycast(..., Infinity)
Mathf.NegativeInfinity负无穷大float.NegativeInfinityfloatMathf.Min(-Infinity, 0) → -Infinity
Mathf.PI圆周率 π(单精度)3.14159274ffloatMathf.Sin(Mathf.PI / 2) → 1

2、基础数学工具方法

方法名作用参数返回值类型示例
Mathf.Abs绝对值value: floatfloatAbs(-5.5f) → 5.5f
Mathf.Sign数值符号(1/-1/0)value: floatfloatSign(-3.2f) → -1
Mathf.Sqrt平方根value: floatfloatSqrt(16) → 4

3、取整与舍入方法

方法名作用参数返回值类型示例
Mathf.Ceil向上取整value: floatfloatCeil(3.2f) → 4.0f
Mathf.Floor向下取整value: floatfloatFloor(3.8f) → 3.0f
Mathf.Round四舍五入(银行家舍入法)value: floatfloatRound(2.5f) → 2.0f
Mathf.CeilToInt向上取整为整数value: floatintCeilToInt(3.2f) → 4
Mathf.FloorToInt向下取整为整数value: floatintFloorToInt(3.8f) → 3

4、极值与数值逼近

方法名作用参数返回值类型示例
Mathf.Max取最大值params float[]floatMax(1, 5, 3) → 5
Mathf.Min取最小值params float[]floatMin(1, 5, 3) → 1
Mathf.MoveTowards固定步长逼近目标值current, target, maxDeltafloatMoveTowards(2, 10, 3) → 5

5、周期与噪声生成

方法名作用参数返回值类型示例
Mathf.PingPong往返循环数值(0→length→0)t: float, length: floatfloatPingPong(Time.time, 5)
Mathf.PerlinNoise生成柏林噪声值(自然随机)x: float, y: floatfloatPerlinNoise(xCoord, yCoord)

6、插值与平滑

方法名作用参数返回值类型示例
Mathf.Lerp线性插值a, b, tfloatLerp(0, 10, 0.5f) → 5
Mathf.LerpUnclamped无限制线性插值a, b, tfloatLerpUnclamped(0, 10, 1.5f) → 15
Mathf.SmoothStepS 形曲线平滑过渡a, b, tfloatSmoothStep(0, 1, 0.5f) → 0.5
Mathf.SmoothDamp阻尼平滑过渡current, target, ref velocity, smoothTimefloatSmoothDamp(pos, targetPos, ref vel, 0.3f)

7、数值限制与映射

方法名作用参数返回值类型示例
Mathf.Clamp限制数值在区间内value, min, maxfloatClamp(10, 0, 5) → 5
Mathf.Clamp01限制数值在 [0,1]value: floatfloatClamp01(-0.5f) → 0
Mathf.Repeat循环数值在 [0, length)t: float, length: floatfloatRepeat(12, 5) → 2
Mathf.InverseLerp计算数值在区间中的比例位置a, b, valuefloatInverseLerp(0, 10, 5) → 0.5

8、其他实用方法

方法名作用参数返回值类型示例
Mathf.Approximately判断浮点数近似相等a: float, b: floatboolApproximately(0.1f, 0.1000001f) → true
Mathf.ClosestPowerOfTwo返回最接近的 2 的幂次value: intintClosestPowerOfTwo(7) → 8
Mathf.NextPowerOfTwo返回大于等于值的 2 的幂次value: intintNextPowerOfTwo(7) → 8
Mathf.Pow计算幂次方base, exponentfloatPow(2, 3) → 8.0f
Mathf.IsPowerOfTwo判断是否为 2 的幂次value: intboolIsPowerOfTwo(8) → true

 


9、Mathf 与 C# Math 的对比

对比维度Unity MathfC# Math
数据类型针对 float 优化,适合实时游戏计算默认使用 double,精度更高但性能开销较大
功能扩展提供游戏开发专用方法(Lerp、SmoothDamp 等)仅提供基础数学运算(Sin、Log 等)
角度转换内置 Deg2Rad 和 Rad2Deg 常量需手动计算(如 Math.PI / 180
性能优化针对 Unity 引擎底层优化,适合高频调用无特殊优化,适合通用计算
典型场景游戏逻辑、动画、物理模拟科学计算、通用编程

10、三角函数与角度处理

方法名作用参数返回值类型示例
Mathf.Sin计算正弦值(弧度)radians: floatfloatSin(Mathf.PI/2) → 1
Mathf.DeltaAngle计算两角度的最小差值current, targetfloatDeltaAngle(350, 10) → 20

就这样,再见!

相关文章:

  • 电子电器架构 --- Zonal架构正在开创汽车电子设计新时代
  • 全流程控制策略,确保AEM制氢安全性
  • 【四川省专升本计算机基础】第二章 计算机软硬件基础(1)
  • C++:内部类
  • upload-labs通关笔记-第7关 文件上传之空格绕过
  • 【开源Agent框架】CAMEL:角色扮演+任务分解
  • YOLOv7训练时4个类别只出2个类别
  • c++ 类的语法3
  • YOLO11解决方案之对象裁剪探索
  • NoSQL数据库复习题目要点
  • upload-labs通关笔记-第8关 文件上传之点绕过
  • 卓力达电铸镍网:精密制造与跨领域应用的创新典范
  • 系统提示学习(System Prompt Learning)在医学编程中的初步分析与探索
  • 现场血案:Kafka CRC 异常
  • Linux补充之vscode连接远端主机
  • 基于 CSS Grid 的网页,拆解页面整体布局结构
  • 创意生图搭配酷炫特效,AIGC直播礼物多元玩法助力平台互动再升级
  • 前端图片自适应全攻略:从基础计算到工程实践
  • 维智定位 Android 定位 SDK
  • 使用 Docker 部署 React + Nginx 应用教程
  • 上海老字号卖黄金,与动漫IP联名两周销售额近亿元
  • “朱雀玄武敕令”改名“周乔治华盛顿”?警方称未通过审核
  • 铁路端午假期运输火车票今日开售,12306提升应对超大规模并发访问需求能力
  • 韧性十足的中国外贸企业:“不倒翁”被摁下去,还会再弹起来
  • 泽连斯基已离开土耳其安卡拉
  • 证监会强化上市公司募资监管七要点:超募资金不得补流、还贷