如何实现lerp平稳运动

诺维·科里斯尼克(NoviKorisnikk)

我只想用lerp在x轴上实现移动对象,以实现平稳的移动。

这是我需要的图片

在此处输入图片说明

我不知道我该如何实现lerp以获得这些值之间的平滑移动,它现在可以工作,但它会传送玩家,这并不是我想要实现的平滑移动

这是我传送玩家的工作代码:

void Start()
{

}


void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        Vector3 desiredPos = new Vector3(transform.position.x + 1.5f, transform.position.y, transform.position.z);
        transform.position = desiredPos;
    }

    if (Input.GetMouseButtonDown(1))
    {
        Vector3 desiredPos = new Vector3(transform.position.x -1.5f, transform.position.y, transform.position.z);
        transform.position = desiredPos;
    }
}

我想实现此功能,但我不知道该怎么做..当我将所有代码更新时,播放器甚至都不会移动..它仅对我有用,当我从文档中复制粘贴所有代码时,但如何我可以将时间从开始方法更改为更新,并且始终可以做到这一点,以便在左右移动时为玩家提供平稳的移动,我不知道是否真的请帮助我。

这是有效的代码,但我不知道如何更改示例。

https://docs.unity3d.com/ScriptReference/Vector3.Lerp.html

雨果

有多种方法。不会使用它,Translate因为这在这里几乎无法控制您,而是例如MoveTowards确保您最后没有过度射击。将其用于具有给定moveSpeed的线性运动

// set move speed in Units/seconds in the Inspector
public float moveSpeed = 1f;

private Vector3 desiredPos;
private bool isMoving;

private void Update()
{
    if (!isMoving && Input.GetMouseButtonDown(0))
    {
        desiredPos = transform.position + Vector3.right * 1.5f;
        isMoving = true;
    }

    if (!isMoving && Input.GetMouseButtonDown(1))
    {
        desiredPos = transform.position - Vector3.right * 1.5f;
        isMoving = true;
    }

    if(isMoving)
    {
        transform.position = Vector3.MoveTowards(transform.position, desiredPos, moveSpeed * Time.deltaTime);

        // this == is true if the difference between both
        // vectors is smaller than 0.00001
        if(transform.position == desiredPos)
        {
            isMoving = false;

            // So in order to eliminate any remaining difference
            // make sure to set it to the correct target position
            transform.position = desiredPos;
        }
    }
}

或者按您的要求使用Vector3.Lerp,例如

// a factor between 0 and 1
[Range(0, 1)] public float lerpFactor;

...

transform.position = Vector3.Lerp(transform.position, desiredPos, lerpFactor);

lerpFactor在我们的情况下,该值必须介于到该值之间,0并且该值永远不会移动,它会直接跳到目标位置。换句话说,将其设置得越接近目标越慢,将其设置得越接近目标就越快。10101

很多人这样做是为了获得“平滑”的运动,但是实际发生的情况是,例如,如果设置0.5为该lerpFactor帧,则将对象放置在当前位置和目标位置之间的中间。

它看起来有些平滑,在开始时移动非常快,而在结束时移动非常慢……但是:实际上,它永远不会真正到达目标位置,只会变得非常缓慢。

对于您的情况而言,这很好,因为无论如何我们都会使用==精度0.00001比较当前位置和目标位置只需记住如何Lerp工作。

但是,有了它,您将无法控制移动速度和持续时间。


如果您想总体上更好地控制(我这样做),我建议您使用协程(这不是绝对必要的,您也可以使用协程Update,但是在我看来,协程更易于维护和跟踪)。

比起无论距离多远,您都可以以固定的持续时间平稳地进行缓入和缓出运动

// set desired move duration in seconds
public float moveDuration = 1;

private bool isMoving;

privtae void Update()
{
    if (!isMoving && Input.GetMouseButtonDown(0))
    {
        StartCoroutine(transform.position + Vector3.right * 1.5f, moveDuration);
    }

    if (!isMoving && Input.GetMouseButtonDown(1))
    {
        StartCoroutine(transform.position - Vector3.right * 1.5f, moveDuration);
    }
}

private IEnumerator Move(Vector3 targetPosition, float duration)
{
    if(isMoving) yield break;

    isMoving = true;

    var startPosition = transform.position;
    var passedTime = 0f;

    do
    {
        // This would move the object with a linear speed
        var lerpfactor = passedTime / duration;

        // This is a cool trick to simply ease-in and ease-out
        // the move speed 
        var smoothLerpfactor = Mathf.SmoothStep(0, 1, lerpfactor);

        transform.position = Vector3.Lerp(startPosition, targetPosition, smoothLerpfactor);

        // increase the passedTime by the time 
        // that passed since the last frame
        passedTime += Time.deltaTime;

        // Return to the main thread, render this frame and go on
        // from here in the next frame
        yield return null;

    } while (passedTime < duration);

    // just like before set the target position just to avoid any
    // under shooting
    transform.position = targetPosition;

    isMoving = false;
}

并且您仍然可以扩展该示例,以同时考虑dtsnace的影响,例如

var actualDuration = duration * Vector3.Distance(startPosition, targetPosition);

然后到处使用actualDuration

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章