首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >流畅的Lerp运动?

流畅的Lerp运动?
EN

Stack Overflow用户
提问于 2018-09-27 10:26:42
回答 5查看 3.4K关注 0票数 7

目前,这是我的脚本,移动球员到周围的场景。我怎么才能让它平稳地移动呢?

代码语言:javascript
复制
void FixedUpdate()
{
    bool running = Input.GetKey(KeyCode.LeftShift);

    float h = Input.GetAxisRaw("Horizontal");
    float v = Input.GetAxisRaw("Vertical");

    bool isWalking = Mathf.Abs(h) + Mathf.Abs(v) > 0;

    movement = ((running) ? runSpeed : walkSpeed) * new Vector3(h, 0.0f, v).normalized;
    if (isWalking)
    {
        transform.position += movement * Time.fixedDeltaTime;
        transform.LookAt(transform.position + movement);
    }

}
EN

回答 5

Stack Overflow用户

发布于 2018-09-27 10:39:21

  1. 创建速度向量:

将移动向量Vector3 velocity = Vector3.zero;

  • Add为速度:

velocity += movement;

  • Add速度恢复到实际位置:

随着时间的推移,通过降低transform.position += velocity;

  • Smooth out速度:

velocity *= 0.975f;

票数 11
EN

Stack Overflow用户

发布于 2018-10-07 08:54:31

根据Time.fixedDeltaTime的定义,FixedUpdate()函数每隔一段固定的时间间隔运行一次(您可以通过TimeManager (固定时间步长)设置它,也可以在运行时通过直接将它设置为一个新值来运行)。

由于您以固定的间隔移动字符位置和旋转,因此根据帧率的不同,字符将以较低的帧率移动很多,或仅以较高的帧率每隔几帧移动一次。

例如,固定时间刻度为0.02秒,游戏以每秒30帧的帧率运行(也称为每0.033秒渲染一次),您的游戏将执行以下操作:

代码语言:javascript
复制
 - [Time: 0.020s] Character position += 0.02
 - [Time: 0.033s] Render frame with character at position 0.02
 - [Time: 0.040s] Character position += 0.02
 - [Time: 0.060s] Character position += 0.02
 - [Time: 0.066s] Render frame with character at position 0.06
 - [Time: 0.080s] Character position += 0.02
 - [Time: 0.099s] Render frame with character at position 0.08
 - [Time: 0.100s] Character position += 0.02
 - [Time: 0.120s] Character position += 0.02
 - [Time: 0.133s] Render frame with character at position 0.12

因此,在这个例子中,你可以看到角色如何以每帧不同的数量向前跳跃,你也不能保证游戏将以什么帧率运行,因此最终可能会变得更糟。

不过,有一些方法可以让你的角色移动得很流畅。

将代码放在FixedUpdate()循环而不是

  1. ()循环中,这将在渲染的每个帧中移动角色的位置。此外,您可以将移动速度乘以自上一帧渲染以来的时间(也称为自上次运行Time.deltaTime ()并移动角色以来的时间)
  2. 使用Vector3.Lerp(..)/Quaterion.Lerp(..)或使用乘以Time.deltaTime的时间/步长值的Vector3.MoveTowards(..)/Quaternion.RotateToward(..)对角色移动进行插值,使其相对于游戏保持平滑移动framerate.
  3. If您的角色具有刚体组件,那么您可以简单地将刚体插值设置为Time.deltaTime,然后通过调用:

characterRigidbody.MovePosition(wantedPosition);characterRigidbody.MoveRotation(wantedRotation);

作为现有转换移动的替代(将代码保留在FixedUpdate()循环中)

但请注意,继续在FixedUpdate()中使用输入.*调用会使轮询它们的次数超过需要的次数,因此,如果您决定这样做,您可能希望将它们移到分割移动代码和输入侦听代码的更新()中。(我开发安卓游戏,所以可能在PC上这不值得担心,但可能仍然值得改变)

不过,这个问题的直接代码块答案可能是尝试一下,这是解释1和2的组合:

代码语言:javascript
复制
// How long in seconds will it take the lerps to finish moving into position
public float lerpSmoothingTime = 0.1f;

private Vector3 targetPosition;
private Quaternion targetRotation;

void Update()
{
    bool running = Input.GetKey(KeyCode.LeftShift);

    float h = Input.GetAxisRaw("Horizontal");
    float v = Input.GetAxisRaw("Vertical");

    bool isWalking = Mathf.Abs(h) + Mathf.Abs(v) > 0;

    movement = ((running) ? runSpeed : walkSpeed) * new Vector3(h, 0.0f, v).normalized;
    if (isWalking)
    {
        targetPosition += movement * Time.deltaTime;
        targetRotation = Quaternion.LookRotation(targetPosition - transform.position);
    }

    // Always lerping as if we suddenly stopped the lerp as isWalking became false the stop would be sudden rather than smoothly moving into position/rotation
    transform.position = Vector3.Lerp(transform.position, targetPosition, Time.deltaTime / lerpSmoothingTime);
    transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, Time.deltaTime / lerpSmoothingTime);    
}

如果你想阅读更多关于平滑移动物体的细节,学习lerps,或者只是想要更多的例子,那么可以在how to fix movement stutter in Unity上查看这个指南。

票数 4
EN

Stack Overflow用户

发布于 2018-10-05 17:58:33

首先,如果您希望Update()方法执行每个帧,则需要将代码放入该方法中。根据项目设置以固定的时间间隔调用FixedUpdate (您可以在编辑->项目设置-> Time ->固定时间步长中对其进行更改)。通常,FixedUpdate()用于与物理相关的东西。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52528524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档