旋转和移动时相机的抖动 - 2D top down Unity

Jittery movement of the camera when rotating AND moving - 2D top down Unity

我正在制作一个 2d 自上而下的游戏,玩家可以在游戏中移动时围绕自己旋转相机。

当玩家在世界各地移动时,一切正常,摄像机可以很好地跟随他。如果他站着不动,那么摄像机旋转也能很好地工作。但是,一旦我开始同时执行这两项操作,相机就会出现抖动,这使得除播放器之外的所有其他对象都抖动。

现在在处理这个问题时,我发现这可能与我使用 rigidbody2d.AddRelativeForce(所以物理学)移动玩家并且他的动作在 FixedUpdate 中检查的事实有关。

https://forum.unity3d.com/threads/camera-jitter-problem.115224/ http://answers.unity3d.com/questions/381317/camera-rotation-jitterness-lookat.html

我已经尝试将我的相机旋转和以下脚本移动到 LateUpdate、FixedUpdate、Update 等等。似乎没有任何效果。我确信相机的移动和导致这种情况的旋转之间存在某种延迟。我想知道是否有人有任何反馈?

我试过禁用 Vsync,但没有完全删除它 我试过内插和外推刚体,虽然有区别,但并没有完全消除它。具有讽刺意味的是,如果我将其设置为 none,效果最好。

脚本:

要跟随角色,应用于将相机作为子对象的游戏对象的脚本

  public class FollowPlayer : MonoBehaviour {

  public Transform lookAt;
  public Spawner spawner;
  private Transform trans;
  public float cameraRot = 3;

  private bool smooth = false;
  private float smoothSpeed = 30f;
  private Vector3 offset = new Vector3(0, 0, -6.5f);

  //test
  public bool changeUpdate;

  private void Start()
  {
      trans = GetComponent<Transform>();
  }

  private void FixedUpdate()
  {
      CameraRotation();
  }

  private void LateUpdate()
  {
      following();
  }

  public void following()
  {

      Vector3 desiredPosition = lookAt.transform.position + offset;

      if (smooth)
      {
          transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
      }
      else
      {
          transform.position = desiredPosition;
      }
  }

  void CameraRotation()
  {
      if (Input.GetKey("q"))
      {
          transform.Rotate(0, 0, cameraRot);
      }

      if (Input.GetKey("e"))
      {
          transform.Rotate(0, 0, -cameraRot);
      }
  }

  public void SetTarget(string e)
  {
      lookAt = GameObject.Find(e).GetComponent<Transform>();
  }

} 应用于Player的角色Controller脚本在FixedUpdate中被调用

      private void HandleMovement()
  {

      if (Input.GetKey("w"))
      {
          rigid.AddRelativeForce(Vector2.up * speed);
      }

      if (Input.GetKey("s"))
      {
          rigid.AddRelativeForce(Vector2.down * speed);
      }

      if (Input.GetKey("a"))
      {
          if (facingRight)
          {
              Flip();
          }
          rigid.AddRelativeForce(Vector2.left * speed);
      }

      if (Input.GetKey("d"))
      {
          if (!facingRight)
          {
              Flip();
          }
          rigid.AddRelativeForce(new Vector2(1,0) * speed);
      }
  }

尝试使用协程。我修改了我的一些脚本以更熟悉您的代码,尝试了一下,但我没有看到任何紧张。希望对你有所帮助。

相机Class:

public class CameraController : MonoBehaviour {

    [SerializeField]
    Transform CameraRotator, Player;

    [SerializeField]
    float rotationSpeed = 10f;

    float rotation;

    bool rotating = true;

    void Start()
    {
        StartCoroutine(RotatingCamera());
    }

    IEnumerator RotatingCamera()
    {
        while (rotating)
        {
            rotation = Input.GetAxis("HorizontalRotation");
            CameraRotator.Rotate(Vector3.up * Time.deltaTime * rotation * rotationSpeed);
            CameraRotator.position = Player.position;
            yield return new WaitForFixedUpdate();
        }
    }

    private void OnDestroy()
    {
        StopAllCoroutines();
    }
}

玩家Class:

public class PlayerMovement : MonoBehaviour {

[SerializeField]
float movementSpeed = 500f;

Vector3 movementVector;
Vector3 forward;
Vector3 right;

[SerializeField]
Transform CameraRotator;

Rigidbody playerRigidbody;

float inputHorizontal, inputVertical;

void Awake()
{
    playerRigidbody = GetComponent<Rigidbody>();

    StartCoroutine(Moving());
}

IEnumerator Moving()
{
    while (true)
    {
        inputHorizontal = Input.GetAxis("Horizontal");
        inputVertical = Input.GetAxis("Vertical");

        forward = CameraRotator.TransformDirection(Vector3.forward);
        forward.y = 0;
        forward = forward.normalized;

        Vector3 right = new Vector3(forward.z, 0, -forward.x);

        movementVector = inputHorizontal * right + inputVertical * forward;

        movementVector = movementVector.normalized * movementSpeed * Time.deltaTime;

        playerRigidbody.AddForce(movementVector);
        yield return new WaitForFixedUpdate();
    }
}

}

我终于解决了这个问题:

首先,我将我的 cameraRotation() 和 follow() 合并为 1 个函数,并给它起了一个更清晰的名称:

    public void UpdateCameraPosition()
{
    if (Input.GetKey("q"))
    {
        transform.Rotate(0, 0, cameraRot);
    }
    else if (Input.GetKey("e"))
    {
        transform.Rotate(0, 0, -cameraRot);
    }

    Vector3 desiredPosition = lookAt.transform.position + offset;

    transform.position = desiredPosition;
}

然后我在处理完运动后直接从角色控制器调用该函数。 fixedUpdate 中的两个调用(handleMovement 和 cameraPosition)。

 void FixedUpdate()
{
    HandleMovement();                         
    cameraController.UpdateCameraPosition(); 
}

抖动消失了。

所以这似乎是暗示,因为正如我之前阅读的帖子所说,两次调用之间存在轻微延迟。但是我未能正确地将它们设置得足够近。

希望这对某人有所帮助。