在 Unity 中移动游戏对象时抖动旋转
Jittery rotation while moving gameobject in Unity
我有一个抖动问题,我在互联网上仔细搜索并尝试了无数解决方案,但 none 奏效了。
本质上,我正在将 2D Enemy GameObject 移向我的玩家,这涉及同时移动和旋转。
一开始它很流畅,但是当我的玩家射击 Enemy 时,由于 RigidBody2D 物理特性导致它向后飞,当它旋转回我的玩家时开始抖动。
此外,当我的敌人在被击中后试图转回我的玩家时,它会努力 aim/rotate 直接对着我的玩家。抖动的时候就是有点吃力地旋转最后20度
我已经尝试了使用速度和 AddForce 进行移动以及使用 FromToRotation、RotateTowards、Lerp 和 Slerp 进行旋转的所有组合。
我尝试过同时使用 Update、LateUpdate 和 FixedUpdate 进行移动和旋转。
我已经尝试将 GameObjects Interpolation 设置为 None、Interpolate 和 Extrapolate。
没有任何效果。
我最好的猜测是我的 RotateEnemy() 在被击中后不知何故对“前进”是什么感到困惑,并且不知道指向玩家什么。
这是一个显示问题的视频:
https://www.youtube.com/watch?v=SJwn4I74znQ&ab_channel=DanielNielsen
这是我的 Enemy 游戏对象上的脚本:
Rigidbody2D _rb;
[SerializeField] GameObject _player;
float _moveSpeed = 2f;
Vector2 _currentVelocity;
Vector2 _targetVelocity;
Vector2 _moveDirection;
Quaternion _targetRotation;
bool _disableEnemy = false;
void Start()
{
_rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// Move player
_moveDirection = _player.transform.position - transform.position;
_moveDirection.Normalize();
}
void FixedUpdate()
{
if (!_disableEnemy)
{
RotateEnemy();
MoveEnemy();
}
}
void MoveEnemy()
{
// Prevent redundacy
_currentVelocity = _rb.velocity;
_targetVelocity = _moveDirection * _moveSpeed;
if (_currentVelocity != _targetVelocity)
{
_rb.velocity = _moveDirection * _moveSpeed;
}
}
void RotateEnemy()
{
_targetRotation = Quaternion.LookRotation(Vector3.forward, _moveDirection);
if (transform.rotation != _targetRotation)
{
transform.rotation = Quaternion.Slerp(transform.rotation, _targetRotation, 10 * Time.deltaTime);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Bullet")
{
StartCoroutine(Damaged());
}
}
private IEnumerator Damaged()
{
_disableEnemy = true;
yield return new WaitForSeconds(0.5f);
_disableEnemy = false;
}
根据您的回复,我建议您致电 Update
中的 RotateEnemy()
。
Update
在每一帧上运行,而 FixedUpdate
不运行 - 它在每个物理刻度上运行,并且每帧可能会出现或多于或少于其中一个。
而且由于我们在 RotateEnemy()
中不处理物理相关的东西,我们应该在 Update()
中调用它
private void Update()
{
// Move player
_moveDirection = _player.transform.position - transform.position;
_moveDirection.Normalize();
if (!_disableEnemy)
{
RotateEnemy();
}
}
我有一个抖动问题,我在互联网上仔细搜索并尝试了无数解决方案,但 none 奏效了。
本质上,我正在将 2D Enemy GameObject 移向我的玩家,这涉及同时移动和旋转。
一开始它很流畅,但是当我的玩家射击 Enemy 时,由于 RigidBody2D 物理特性导致它向后飞,当它旋转回我的玩家时开始抖动。
此外,当我的敌人在被击中后试图转回我的玩家时,它会努力 aim/rotate 直接对着我的玩家。抖动的时候就是有点吃力地旋转最后20度
我已经尝试了使用速度和 AddForce 进行移动以及使用 FromToRotation、RotateTowards、Lerp 和 Slerp 进行旋转的所有组合。
我尝试过同时使用 Update、LateUpdate 和 FixedUpdate 进行移动和旋转。
我已经尝试将 GameObjects Interpolation 设置为 None、Interpolate 和 Extrapolate。
没有任何效果。
我最好的猜测是我的 RotateEnemy() 在被击中后不知何故对“前进”是什么感到困惑,并且不知道指向玩家什么。
这是一个显示问题的视频:
https://www.youtube.com/watch?v=SJwn4I74znQ&ab_channel=DanielNielsen
这是我的 Enemy 游戏对象上的脚本:
Rigidbody2D _rb;
[SerializeField] GameObject _player;
float _moveSpeed = 2f;
Vector2 _currentVelocity;
Vector2 _targetVelocity;
Vector2 _moveDirection;
Quaternion _targetRotation;
bool _disableEnemy = false;
void Start()
{
_rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// Move player
_moveDirection = _player.transform.position - transform.position;
_moveDirection.Normalize();
}
void FixedUpdate()
{
if (!_disableEnemy)
{
RotateEnemy();
MoveEnemy();
}
}
void MoveEnemy()
{
// Prevent redundacy
_currentVelocity = _rb.velocity;
_targetVelocity = _moveDirection * _moveSpeed;
if (_currentVelocity != _targetVelocity)
{
_rb.velocity = _moveDirection * _moveSpeed;
}
}
void RotateEnemy()
{
_targetRotation = Quaternion.LookRotation(Vector3.forward, _moveDirection);
if (transform.rotation != _targetRotation)
{
transform.rotation = Quaternion.Slerp(transform.rotation, _targetRotation, 10 * Time.deltaTime);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Bullet")
{
StartCoroutine(Damaged());
}
}
private IEnumerator Damaged()
{
_disableEnemy = true;
yield return new WaitForSeconds(0.5f);
_disableEnemy = false;
}
根据您的回复,我建议您致电 Update
中的 RotateEnemy()
。
Update
在每一帧上运行,而 FixedUpdate
不运行 - 它在每个物理刻度上运行,并且每帧可能会出现或多于或少于其中一个。
而且由于我们在 RotateEnemy()
中不处理物理相关的东西,我们应该在 Update()
private void Update()
{
// Move player
_moveDirection = _player.transform.position - transform.position;
_moveDirection.Normalize();
if (!_disableEnemy)
{
RotateEnemy();
}
}