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