Unity3D之对Vector3.Lerp插值的理解

什么是插值

对于刚接触unity的同学来说,插值可能是比较难理解的概念之一。
插值:

在离散数据的基础上补插连续函数,使得这条连续曲线通过全部给定的离散数据点。插值是离散函数逼近的重要方法,利用它可通过函数在有限个点处的取值状况,估算出函数在其他点处的近似值。插值:用来填充图像变换时像素之间的空隙。

以上是百度百科里的解释,感觉太官方话了。下面结合unity中的Vector3.Lerp具体的谈谈什么是插值,插值是如何计算的。

Vector3.Lerp

引导

有时,我们在做游戏时会发现有些跟随动作不够圆滑,这时,一般会考虑到插值。所以对插值的理解是必需的。比如摄像机跟随主角。当主角移动时,希望摄像机以一种线性或者非线性的速度跟随主角。那么,这个“以一种线性或者非线性的速度”就是用插值办到的。

计算公式

插值是数学上的一个概念,在这里用公式表示就是:from + (to - from) * t;这也就是Lerp的返回值(用这个公式分别算出x,y,z)。

static function Lerp (from : Vector3, to : Vector3, t : float) : Vector3
from 是起始的位置,to是目标位置,按照数字t在from到to之间插值。这句话比较难理解,下面举个例子。

例一

public class test : MonoBehaviour
{
    Vector3 start = new Vector3(1,1,1);
    Vector3 end = new Vector3(2,2,2);
    Vector3 result;
    void Update ()
    {
        result = vector3.Lerp(start, end, 0.5f)
        Debug.Log(result.ToString());
    }
}

结果:

这和我们用公式算出来的如出一辙。现在我们再看一个具体的例子

例二

//在1秒时间动画位置移动从from开始到to结束。(这是官方的例子)
public class example:MonoBehaviour
{
    public Transform start;
    public Transform end;
    void Update()
    {
        transform.position = Vector3.Lerp(start.position, end.position, Time.time)
    }
}

结果:

位置移动从start开始到end结束,这好理解,但是为什么是1秒呢?
Time.time是从0开始随时间增加的。
例1的t是一个固定的值,返回一个固定的向量。此时t是变量,在不断增加。那么:

当Time.time = 0时
—>transform.position = start.position,位置没有变化;
当Time.time从0趋向于1时
—>transform.position 不断接近start.position,该脚本是挂在start物体上的,所以start会不断靠近end。

那么问题来了,当Time.time>1的时候,会怎么样呢?
额(⊙o⊙)…
这应该不会发生。由上面的公式from + (to - from) * t可知,当t=1时,to - from = 0,此时t就无效了。

例1是从静态角度看,例2是从动态角度看的(两个变量,一个是时间在变化,一个是位置在变化)。

想一想例2,如果不是Time.time,而是0.5,会怎么样?(只看一个变量)

由图易知:A物体会不断以0.5的比例无限接近于B。当这个距离小于等于最小极限时,unity会当做0看待。此时就停下了。

思考一下

如果上面都理解了,那么看官方的第二个例子就没什么问题了,试一试吧!

//像弹簧一样跟随目标物体
public class example : MonoBehaviour
{
    public Transform target;
    public float smooth = 5.f;
    void Update()
    {
        transform.position = Vector3.Lerp(transform.position, target.position, Time.deltaTime * smooth);
    }
}