【问题标题】:Vector3.Lerp isn't moving the whole wayVector3.Lerp 没有完全移动
【发布时间】:2021-03-10 20:57:36
【问题描述】:

基本上我正在尝试为我的自上而下的 RPG 风格游戏创建一个滚动系统,但是当我执行 Vector3.Lerp 时,它并没有完全移动

代码是:

public void CheckSpaceKey()
{
    if (exhausted == false)
    {
        if (Input.GetKey(KeyCode.Space) && canRoll)
        {
            if (rollDir == RollDir.Up)
            {
                Vector3 rollStartPos = new Vector3(transform.position.x, transform.position.y, -1.0f);
                Vector3 rollEndPos = new Vector3(transform.position.x, transform.position.y + 3, -1.0f);
                transform.position = Vector3.Lerp(rollStartPos, rollEndPos, Time.deltaTime);
                canRoll = false;
                playerStats.stamina -= 10;
                Invoke("RollCooldown", 1.5f);
            }
        }
    }
}

public void RollCooldown()
{
    canRoll = true;
}

这应该让我的玩家向上移动 3 个单位,但它实际上是移动了一个 0.35 到 0.45 左右的随机数。

CheckSpaceKey 也在更新中被调用

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    Lerp 不会做你认为的那样。假设Time.deltaTime 大约是 1/60,它会将单元移动到目的地的 1/60,仅此而已。

    考虑使用一个协程,在每一帧更新Lerpt 参数:

    public void CheckSpaceKey()
    {
        // by the way, this could just be `if (!exhausted)`
        // although some coding guidelines require this format below
        if (exhausted == false)
        {
            if (Input.GetKey(KeyCode.Space) && canRoll)
            {
                if (rollDir == RollDir.Up)
                {
                    StartCoroutine(DoRoll(Vector3.up * 3));
                }
            }
        }
    }
    
    IEnumerator DoRoll(Vector3 offset)
    {  
        float duration = 1f;
    
        canRoll = false;
        playerStats.stamina -= 10;
        Invoke("RollCooldown", 1.5f);
    
        Vector3 rollStartPos = new Vector3(transform.position.x, transform.position.y, -1.0f);
        Vector3 rollEndPos = rollStartPos + offset;
    
        float t = 0;
        while (t < 1f)
        {
            t = Mathf.Min(1f, t + Time.deltaTime/duration);
            transform.position = Vector3.Lerp(rollStartPos, rollEndPos, t);
            yield return null; 
        }
    }
    
    public void RollCooldown()
    {
        canRoll = true;
    }
    

    【讨论】:

      【解决方案2】:

      这不会移动 3 个单位,你调用 transform.position 仅在 if 情况下,并且每 1.5 秒访问一次 if 情况。 Lerp 不会每帧更新你的位置,而只会更新它被调用的帧,如果你的对象不断移动,你必须不断更新你的位置,你应该在第一个 if 中创建 rollStartPos 和 rollEndPos 并创建 add

      else{ 
           time += Time.deltaTime;
           transform.position = Vector3.Lerp(rollStartPos, rollEndPos, time);
      }
      

      在第二个如果。这样,除非球(?)用尽,否则它将一直保持到 rollEndPos,如果即使在用尽时它也应该滚动,则需要更新第一个 if 之外的位置

      【讨论】:

      • 对,谢谢@ruzihm,我一开始写的很正确,但出于某种原因编辑了它,我编辑它时似乎有点分心。我将再次将 transform.position 更改为 rollStartPos。
      猜你喜欢
      • 2022-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-07
      • 1970-01-01
      相关资源
      最近更新 更多