Unity中正确使用Lerp

本文转自blueraja
Unity官方示例中关于Lerp()函数的使用并非匀速插值,原因是Lerp()的from参数是在不断更新的,若想实现匀速插值效果,应按照类似下述方法。

using UnityEngine;
using System.Collections;
 
public class LerpOnSpacebarScript : MonoBehaviour
{
    /// <summary>
    /// The time taken to move from the start to finish positions
    /// </summary>
    public float timeTakenDuringLerp = 1f;
 
    /// <summary>
    /// How far the object should move when 'space' is pressed
    /// </summary>
    public float distanceToMove = 10;
 
    //Whether we are currently interpolating or not
    private bool _isLerping;
 
    //The start and finish positions for the interpolation
    private Vector3 _startPosition;
    private Vector3 _endPosition;
 
    //The Time.time value when we started the interpolation
    private float _timeStartedLerping;
 
    /// <summary>
    /// Called to begin the linear interpolation
    /// </summary>
    void StartLerping()
    {
        _isLerping = true;
        _timeStartedLerping = Time.time;
 
        //We set the start position to the current position, and the finish to 10 spaces in the 'forward' direction
        _startPosition = transform.position;
        _endPosition = transform.position + Vector3.forward*distanceToMove;
    }
 
    void Update()
    {
        //When the user hits the spacebar, we start lerping
        if(Input.GetKey(KeyCode.Space))
        {
            StartLerping();
        }
    }
 
    //We do the actual interpolation in FixedUpdate(), since we're dealing with a rigidbody
    void FixedUpdate()
    {
        if(_isLerping)
        {
            //We want percentage = 0.0 when Time.time = _timeStartedLerping
            //and percentage = 1.0 when Time.time = _timeStartedLerping + timeTakenDuringLerp
            //In other words, we want to know what percentage of "timeTakenDuringLerp" the value
            //"Time.time - _timeStartedLerping" is.
            float timeSinceStarted = Time.time - _timeStartedLerping;
            float percentageComplete = timeSinceStarted / timeTakenDuringLerp;
 
            //Perform the actual lerping.  Notice that the first two parameters will always be the same
            //throughout a single lerp-processs (ie. they won't change until we hit the space-bar again
            //to start another lerp)
            transform.position = Vector3.Lerp (_startPosition, _endPosition, percentageComplete);
 
            //When we've completed the lerp, we set _isLerping to false
            if(percentageComplete >= 1.0f)
            {
                _isLerping = false;
            }
        }
    }
}

最后附上Lerp()的内部实现:

public static Vector3 Lerp(Vector3 start, Vector3 finish, float percentage)
{
    //Make sure percentage is in the range [0.0, 1.0]
    percentage = Mathf.Clamp01(percentage);
 
    //(finish-start) is the Vector3 drawn between 'start' and 'finish'
    Vector3 startToFinish = finish - start;
 
    //Multiply it by percentage and set its origin to 'start'
    return start + startToFinish * percentage;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,251评论 25 708
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,923评论 18 139
  • 转载一篇高质量博文,原地址请戳这里转载下来方便今后查看。1 背景不能只分析源码呀,分析的同时也要整理归纳基础知识,...
    Elder阅读 1,953评论 0 24
  • 早晨的时候,穿过这条路。阳光刚刚普照,一切都有种金光闪闪的样子。我很想停留下来,享受这段不易得的时光...
    阳阿薤露阅读 256评论 0 0
  • 直到今天,我才明白,好多事情,远远没有你想的那么简单!说好相爱的人,除了别的原因,距离是最大的阻碍!不在身边的...
    翩翩若无阅读 217评论 0 0