Enemy jitters when camera follows the player

I have an enemy that follows or retreats from player based on the distance.

It all works fine until i make camera follow the player. When it does, enemy starts jittering while moving.

Here’s the scripts

Player Movement:

public class Movement : MonoBehaviour
{
    public float moveSpeed = 5;

    private Rigidbody2D rb;
    [SerializeField] private Camera cam;

    private Vector2 movement;
    private Vector2 mousePos;

    private void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        cam = FindObjectOfType<Camera>();
    }

    private void Update()
    {
        movement.x = Input.GetAxisRaw("Horizontal");
        movement.y = Input.GetAxisRaw("Vertical");

        mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
    }

    private void FixedUpdate()
    {
        rb.AddForce(movement * moveSpeed, ForceMode2D.Impulse);

        Vector2 lookDir = mousePos - rb.position;
        float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90;
        rb.rotation = angle;
    }
}

Camera follow:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CamScript : MonoBehaviour
{
    private Camera cam;
    private Transform playerPos;

    private void Start()
    {
        cam = GetComponent<Camera>();
        playerPos = GameObject.FindGameObjectWithTag("Player").transform;
    }

    private void Update()
    {
        transform.position = new Vector3(playerPos.position.x, playerPos.position.y, -10);
    }
}

Enemy movement:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour
{
    [SerializeField] float speed = 3;
    public bool isAggro = false;

    private Rigidbody2D rb;
    public Transform player;

    [Header("Distances")]
    [SerializeField] float followDistance;
    [SerializeField] float retreatDistance;
    private float distance;

    private void OnEnable()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    private void FixedUpdate()
    {
        if (!isAggro) return;

        distance = Vector2.Distance(transform.position, player.position);

        if (distance > followDistance)
        {
            rb.MovePosition(Vector2.MoveTowards(transform.position, player.position, speed * Time.deltaTime));
        }
        else if (distance < retreatDistance)
        {
            rb.MovePosition(Vector2.MoveTowards(transform.position, player.position, -speed * Time.deltaTime));
        }
    }
}

Camera stuff is pretty tricky… you may wish to consider using Cinemachine from the Unity Package Manager.

There’s even a dedicated forum: Unity Engine - Unity Discussions

If you insist on doing it yourself, be sure you follow physics objects from FixedUpdate() or LateUpdate().

Here’s why:

Here is some timing diagram help:

Two good discussions on Update() vs FixedUpdate() timing:

1 Like

Have you turned on Interpolation in the rigidbody settings for your enemy?

I installed cinamachine and set it to follow the player from inspector, but the enemy still jitters, does that mean the problem is in the enemy movement?

Yes, i tried also switching it to extrapolate but it only helped a little

Ok so i spent 3 hours trying everything and of course the solution was super simple.

Turns out the player himself didn’t have any interpolation, set it to Interpolate and everything is fixed!

2 Likes