旋转和移动时相机的抖动 - 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();
}
抖动消失了。
所以这似乎是暗示,因为正如我之前阅读的帖子所说,两次调用之间存在轻微延迟。但是我未能正确地将它们设置得足够近。
希望这对某人有所帮助。
我正在制作一个 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();
}
抖动消失了。
所以这似乎是暗示,因为正如我之前阅读的帖子所说,两次调用之间存在轻微延迟。但是我未能正确地将它们设置得足够近。
希望这对某人有所帮助。