旋转和移动时相机的抖动运动 - 2D自上而下Unity

时间:2017-05-09 18:57:49

标签: unity3d camera rotation jitter

我正在制作一款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,更新你的名字。似乎没什么用。我确信相机的移动和引起这种情况的旋转之间存在某种延迟。我想知道是否有人有任何反馈意见?

我已尝试禁用Vsync,但未完全删除它 我已经尝试过插入和外推刚体,尽管存在差异但它并没有完全消除它。具有讽刺意味的是,如果我将它设置为无,那么效果最好。

脚本:

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

  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>();
  }

} 应用于播放器的角色控制器,脚本在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);
      }
  }

2 个答案:

答案 0 :(得分:1)

尝试使用Coroutines。我修改了一些我的脚本,使你的代码更熟悉,尝试过,我没有看到任何紧张。我希望这会对你有所帮助。

相机类:

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();
    }
}

玩家等级:

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();
    }
}

}

答案 1 :(得分:0)

我最终解决了这个问题:

首先,我将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;
}

然后我在处理动作后直接从角色控制器调用该函数。两个调用(handleMovement&amp; cameraPosition)都在fixedUpdate中。

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

并且抖动消失了。

所以这似乎是暗示,因为我读过的帖子之前的两个电话之间有一点延迟。但是我无法将它们合适地设置得足够接近。

希望这有助于某人。