当我在 Unity 中让一个对象面对鼠标光标时,它最终会偏移

When I make an object face a mouse cursor in Unity it eventually offsets

我制作了一个让玩家指向鼠标光标的脚本,但最近我发现了一个错误。当我过度移动鼠标光标时(例如,当我在对象周围旋转鼠标时,导致对象四处移动。),对象最终指向鼠标应该在的位置。例如,光标会向对象发出信号让其注视它,而对象最终看起来有一点偏差,在快速移动后感觉很奇怪。我怎样才能使对象总是面对光标,即使我尽可能多地移动光标,也没有没有偏移。

            private void LateUpdate()
{
    Vector3 lookAtPoint = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    Vector3 mousePoint = new Vector3(lookAtPoint.x, lookAtPoint.y, 0);

    float angle = getAngle(transform.position, mousePoint);
    transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, angle), 9f * Time.deltaTime);

    float getAngle(Vector3 currentLocation, Vector3 mouseLocation)
    {
        float x = mouseLocation.x - currentLocation.x;
        float y = mouseLocation.y - currentLocation.y;

        return angle = Mathf.Rad2Deg * Mathf.Atan2(y, x);

    }
}

看起来这取决于您使用 Quaternion.Lerp() 的方式。特别是最后一个参数 - 它是您提供的介于 0f 和 1f 之间的值,它不适合您 auto-increment。

因此,要解决此问题,您要做的是在某处保存浮动。当您移动鼠标时(鼠标位置自上一帧以来已更改),然后再次从 0f 开始该值。然后每帧以某个值递增它,直到它等于或大于 1f。

这样做不仅会修复您的错误。根据您的增量速度,它会为您提供平滑的旋转效果。下面是一个例子。

internal class SomeClass : MonoBehaviour
{
  private float lerpAmount = 0f;
  private Vector3 cachedMousePosition = Vector3.zero;
  
  private void LateUpdate()
  {
    var mousePosition
      = Camera.main.ScreenToWorldPoint(Input.mousePosition)
      * new Vector3(1, 1, 0);
    
    bool recalculateRotation = false;
    if (this.cachedMousePosition != mousePosition)
    {
      this.lerpAmount = 0f;
      recalculateRotation = true;
    }

    if (this.lerpAmount < 1f)
    {
      this.lerpAmount = Mathf.Min(this.lerpAmount + Time.deltaTime, 1f);
      recalculateRotation = true;
    }

    if (recalculateRotation)
    {
      float angle = getAngle(transform.position, mousePoint);
      transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.Euler(0, 0, angle), this.lerpAmount);
    }

    float getAngle(Vector3 currentLocation, Vector3 mouseLocation)
    {
      float x = mouseLocation.x - currentLocation.x;
      float y = mouseLocation.y - currentLocation.y;

      return angle = Mathf.Rad2Deg * Mathf.Atan2(y, x);

    }
  }