Mathf类

本文深入解析Unity中的数学工具,包括转换、插值和平滑阻尼等核心功能。通过实例演示了如何利用这些工具实现平滑过渡和精确控制,非常适合游戏开发者学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

属性:

Mathf.Deg2Rad 表示从角度到弧度转变的常量值,其值为(2*Mathf.PI)/360

Mathf.Rad2Deg 表示从弧度到角度转变的常量值,其值为360/(2*Mathf.PI)

方法:

Clamp 返回有限范围值

public static float Clamp(float value, float min, float max);

public static int Clamp(int value, int min, int max);

此方法用来返回有范围限制的value值,当value在范围[min,max]内时返回value值;当value<min时返回min值;当value>max时返回max值。

DeltaAngle 最小增量角度

public static float DeltaAngle(float current, float target);
参数: current 当前角度
    target 目标角度
功能:此方法用于返回从参数值current到target的最小增量角度值。计算方法为,首先将current和target按照360度为一周
    换算到区间(-180,180]中,设current和target换算后的值分别对应c和t,他们在坐标轴中的夹角为e(0<= e <=180),
    则若c经过顺时针旋转e度能到达t,则返回值为e,如下图,若c经过逆时针旋转e度能到达t,则返回值为-e,如下图

     

Lerp 返回两数之间的插值

public static float Lerp(float from, float to, float t);
此方法用来返回from,to之间的插值,t的范围是[0,1]
当t等于0时返回from
当t等于1时返回to
当t等于0.5时返回(from to)/2

SmoothStep 返回两数之间的平滑插值

public static float SmoothStep(float from, float to, float t);
此方法用来返回from,to之间的插值,t的范围是[0,1]
该方法和Lerp方法类似,不同的是插值的增长速度会先快后慢

我们写个例子来看一下Lerp和Smooth的不同
在场景中创建两个立方体Cube和一个球Sphere,让两个立方体运动到球Sphere处,两个立方体的移动距离分别使用Lerp和SmoothStep运算


创建脚本SmoothStep.cs挂在红色的立方体上
代码
public class SmoothStep : MonoBehaviour {

    public float minimum = 0.0F;
    public float maximum = 10.0F;
    void Update()
    {
        float smoothStepvalue = Mathf.SmoothStep(minimum, maximum, Time.time);
        transform.position = new Vector3(smoothStepvalue, 1, 0);
    }
}

创建脚本Lerp.cs挂在白色的立方体上
代码
public class Lerp : MonoBehaviour {

    // Use this for initialization
    public float minimum = 0.0F;
    public float maximum = 10.0F;
	// Update is called once per frame
	void Update () {
        float lerpValue = Mathf.Lerp(minimum, maximum, Time.time);
        transform.position = new Vector3(lerpValue, -2, 0);
    }
}

效果


SmoothStep的速度曲线增长方式和下图中的f1差不多


SmoothDamp 此方法模拟平滑阻尼运动

public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime);
功能:模拟平滑阻尼运动,并返回模拟的插值,物体越靠近目标值,加速度越小
参数:current 起始值
   target 目标值
   currentVelocity 当前帧速度
   smoothTime 预计平滑的时间,即到达目标值的时间
   maxSpeed 当前帧的最大速度值
   deltaTime 平滑时间,值越大返回的值越大 一般用Time.deltaTime

例子:在场景中创建一个立方体和一个球体,让立方体采用平滑阻尼的方式运动到球体位置
    
创建脚本SmoothDamp.cs并把它挂在立方体上
代码:
public class SmoothDamp : MonoBehaviour
{
    public Transform target;
    public float smoothTime = 1F;
    private float yVelocity = 0.0F;
    void Update()
    {
        float newPosition = Mathf.SmoothDamp(transform.position.x, target.position.x, ref yVelocity, smoothTime);
        transform.position = new Vector3(newPosition, transform.position.y, transform.position.z);
    }
}

效果:


SmoothDampAngle 阻尼旋转

public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime);
功能:模拟角度的平滑阻尼旋转,并返回模拟的插值,物体越靠近目标值,加速度越小
参数:current 起始值
   target 目标值
   currentVelocity 当前帧速度
   smoothTime 预计平滑的时间,即到达目标值的时间
   maxSpeed 当前帧的最大速度值
   deltaTime 平滑时间,值越大返回的值越大 一般用Time.deltaTime
例子:创建一个立方体和脚本SmoothDampAngle.cs,把脚本挂在立方体上
代码
public class SmoothDampAngle : MonoBehaviour {

    public Transform target;
    public float smooth = 0.3F;
    public float distance = 5.0F;
    private float yVelocity = 0.0F;
    void Update()
    {
        float yAngle = Mathf.SmoothDampAngle(transform.eulerAngles.y, 180, ref yVelocity, smooth);
        transform.rotation = Quaternion.Euler(0, yAngle, 0);
    }
}

效果


LerpAngle 角度插值

public static float LerpAngle(float a, float b, float t);
参数:a 起始角度
    b 结束角度
    t 插值系数
功能:用来返回从角度a到角度b之间的一个插值
说明:
1) a和b可以为任意的float类型的数值,a可以大于b,也可以小于b,他们之间没有任何约束关系。
2) 插值系数t的有效取值范围为[0,1]
3)插值计算之前需要对a,b进行规范化,使a,b在范围[0,360]
  a = 360*k + a,其中k为整数
设对a,b进行规范化后的值分别为a',b'.设a',b'之间的插值为c,c可能是a'-b',也可能是b'-a',总之使c的范围为[0,180].
当a'沿着顺时针方向旋转c度与b'重合时,则插值计算方式为:f=a-c*t, 
当a'沿着逆时针方向旋转c度与b'重合时,则插值计算方式为:f=a+c*t,


代码
public class LerpAngle : MonoBehaviour {

	// Use this for initialization
	void Start () {
        float a,b,f;
        a = -50.0f;
        b = 400.0f;
        f = Mathf.LerpAngle(a, b, 0.3f);
        //a规范化后的值为360-50=310,b规范化后的值为-360+400=40
        //a沿逆时针方向经90度后到达b,所以插值返回值f=a+c*t=-50+90*0.3

        a = 400f;
        b = -50f;
        f = Mathf.LerpAngle(a, b, 0.3f);
        //a规范化后的值为-360+400=40,b规范化后的值为360-50=310
        //a沿顺时针方向经90度后到达b,所以插值返回值f=a-c*t=400-90*0.3
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值