1

I have an issue with jittery movement and I have searched the internet thin and tried countless solutions, but none have worked.

Essentially, I am moving a 2D Enemy GameObject towards my player, which involves moving and rotating at the same time.

At the start it is smooth, but when my player shoots the Enemy, causing it to fly backwards because of the RigidBody2D physics, it starts jittering when it rotates back towards my player.

Also, when my enemy tries to rotate back towards my player after getting hit, it struggles to aim/rotate directly at my player. It's just kind of struggling to rotate the last 20 degrees while jittering.

I have tried EVERY combination of using velocity and AddForce for movement, and using FromToRotation, RotateTowards, Lerp, and Slerp for rotation.

I have tried using both Update, LateUpdate, and FixedUpdate for either or both moving and rotating.

I have tried setting the GameObjects Interpolation to None, Interpolate and Extrapolate.

Nothing works.

My best guess is that my RotateEnemy() somehow gets confused about what "forward" is after getting hit, and doesn't know what to point at the player.

Here is a video showing the issue:

https://www.youtube.com/watch?v=SJwn4I74znQ&ab_channel=DanielNielsen

Here is the script I have on my Enemy gameobject:

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;
}
Dani
  • 13
  • 4
  • You are callling `RotateEnemy()` in `FIxedUpdate` so try `transform.rotation = Quaternion.Slerp(transform.rotation, _targetRotation, 10 * Time.fixedDeltaTime);` – Digvijaysinh Gohil Apr 11 '22 at 10:54
  • Thanks for the reply. :) From my understanding, whenever you use Time.deltaTime in FixedUpdate, it automatically gets converted to Time.fixedDeltaTime. But I tried changing it to Time.fixedDeltaTime and the issue still persists. :/ – Dani Apr 11 '22 at 11:07

1 Answers1

0

Based on your reply I would suggest you to call your RotateEnemy() in Update.

Update runs on every frame, where FixedUpdate does not - it runs per physics tick, and more or less than one of those may occur each frame.

And since we are not handling physics related stuff in RotateEnemy() we should call it in Update()

private void Update()
{
    // Move player
    _moveDirection = _player.transform.position - transform.position;
    _moveDirection.Normalize();

    if (!_disableEnemy)
    {
        RotateEnemy();
    }
}
Digvijaysinh Gohil
  • 1,367
  • 2
  • 15
  • 30
  • Thanks! This solves the "aim at the player" issue, however the enemy movement gets incredibly choppy after doing so. Do you know the reason behind this? :) – Dani Apr 11 '22 at 11:16
  • I tried changing from using a velocity type movement, to a MoveTowards movement, and moved it into Update instead. The solves the choppy movement, but only until the Enemy is hit with a bullet. Then it becomes choppy again. :/ – Dani Apr 11 '22 at 11:36
  • After removing my RigidBody2D from the enemy, I can see that it solves the choppyness, but it also means removing the "knockback" effect hehe. So the issue is RigidBody2D related... Just don't know what – Dani Apr 11 '22 at 11:47
  • FIXED IT! Adding a higher Drag on the RigidBody2D solved the issue. Apparently without a drag, the physics would cause the object to keep "flying backwards" while I was trying to manually move the gameobject using MoveTowards. ':D So I had to stop the gameobjects "knockback" first. TY so much for helping me figure out the solution ^^ – Dani Apr 11 '22 at 11:52
  • You will need `RigidBody2D` or you won't be able to detect the collision, and your `MoveEnemy()` must use `velocity` or `AddForce` to handle movement, and since we are handling physics stuff we must call it in `FixedUpdate`. could you post a screenshot of your `Rigidbody2D` settings? – Digvijaysinh Gohil Apr 11 '22 at 11:52