【问题标题】:Camera is following not smoothly相机跟随不顺畅
【发布时间】:2018-01-08 02:34:39
【问题描述】:

相机应该跟随一个二维字符,这里是代码

void LateUpdate ()
{
    var to = target.position;
    to.z = transform.position.z;
    var newPos = Vector3.Lerp(transform.position, to, speed * Time.deltaTime);
    transform.position = newPos;
    newPos.z = to.z;
    Debug.DrawRay(newPos, Vector3.up, Color.green, 5);
}

我还画了角色和相机的位置。

红线是角色的位置,绿线是相机的位置

我做错了什么?

更新:

我发现了一些有趣的东西。下图中的绿线是由 Vector3.Lerp 在 LateUpdate 方法中移动的相机的位置。黄线是我在 FixedUpdate 方法中为角色的 Rigidbody2D 设置的角色的位置,红线是从相机的 LateUpdate 内部看到的角色变换的位置。

我想说的是,角色的实际位置是由它的 Rigidbody2D 组件驱动的。通过更改 Rigidbody2D 的“Interpolate”选项,我们可以获得不同的结果。

问题在于,即使我在每个 FixedUpdate 刻度都向 Rigidbody2D 的位置添加相同的值,结果也不是那么一致。有时新旧位置之间的距离大于应有的距离。

加上我们在 LateUpdate 方法中设置相机的位置,它的更新率与 FixedUpdate 不同,所以即使我们将新位置设置为角色的变换,而不是 Rigidbody2D,相机的移动仍然不会流畅,因为角色的速度每帧都会不同。

目前我只有一个解决方案。

  1. 将角色的新位置设置为其变换,而不是 Rigidbody2D
  2. 在其 FixedUpdate 中更改相机的位置,而不是在 LateUpdate 中。

那么位置会是这样的

但是由于相机的位置是在FixedUpdate中设置的,它不会像它可能的那么平滑,而且我不确定角色的碰撞检测是否会起作用,因为我们直接设置了它的位置到它的变换。

【问题讨论】:

  • 尝试 UnityWiki 中的 SmoothCamera 脚本,您必须进行更改以仅支持 2D 跟随(只需沿 z 轴常量设置位置)。这是链接:UnityWikiUnityWikiCached
  • 我尝试了简单的脚本和改进的脚本,仍然有问题,我认为问题出在其他地方,而不是在代码中
  • 是只在设备上不流畅还是在编辑器和设备上都不流畅?也可以尝试在任何脚本的唤醒中设置它Application.targetFrameRate = 60;
  • 在设备和编辑器中也不流畅,我设置了帧率但没有帮助
  • 尝试将质量设置设为 Fantastic。如果问题仍然存在,请尝试此处提到的其他一些设置forum.unity3d.com/threads/…

标签: c# unity3d camera 2d


【解决方案1】:

问题可能来自您如何使用插值来确定移动相机的距离。

我不知道Vector3.Lerp 的行为是否会推断第三个参数(其分数)是否高于 1.0,但我怀疑这可能是问题所在(特别是如果在帧,speed * Time.DeltaTime 高于 1.0)

更好的方法(消除 lerp)可能是自己根据速度和时间对距离进行插值;

void LateUpdate ()
{
    var to = target.position;
    to.z = transform.position.z;
    //you can just multiply a Vector3 with a float 
    //so we can do the interpolation maths ourselves like this :
    var distanceToMove = (to - transform.position) * speed * Time.deltaTime; 
    var newPos = transform.position + distanceToMove;
    transform.position = newPos;
    newPos.z = to.z;
    Debug.DrawRay(newPos, Vector3.up, Color.green, 5);
}

(如果这让人感到困惑,这里是经过清理的版本以使其更简洁)

void LateUpdate ()
{
    var to = target.position;
    to.z = transform.position.z;
    transform.position += (to - transform.position) * speed * Time.deltaTime; ;
    Debug.DrawRay(transform.position, Vector3.up, Color.green, 5);
}

【讨论】:

  • +1,这不是 lerp 应该使用的方式。第三个参数是百分比,你不应该在这里使用增量时间。这个例子可能可以用 MoveTowards 代替,但为了更好的相机效果,我更喜欢 SmoothDamp :线性插值有一种“无聊”的感觉。
  • welp,我尝试了你们建议的两种变体,但看起来并没有改变。我还在 Vector3.Lerp 函数中使用了一个介于 0 和 1 之间的值(大约 0.1),我认为使用 Time.deltaTime 可以使相机移动的速度独立于帧速率
  • @ChazAshley 使用 Time.DeltaTime 将考虑渲染每一帧所需的时间差异,因此应该消除速度和帧速率的波动。在您的代码中使用 Lerp 有点危险,因为它执行插值的方式。从我在您的调试屏幕截图中可以看到,每 9 帧左右就会出现问题。尽管lateupdate 是推荐的方法,但我对此表示怀疑。尝试将代码移至update 时是否仍然出错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 2015-12-12
  • 1970-01-01
  • 2017-08-28
  • 2016-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多