2D Animation Setting Every Frame

When the player is not in attack range and the NPC goes into Suspicion it should idle for a few seconds and then resume patrolling. Instead the animation keeps repeating and then it goes back to patrolling with this repeating animation.

Here’s a recording of what’s occuring:

public class AIController : MonoBehaviour
{
    [SerializeField] float suspicionTime = 3f;

    float timeSinceLastSawPlayer = Mathf.Infinity;

    private void Update()
    {
        if (health.IsDead()) { return; }

        if (InAttackRangeOfPlayer() && fighter.CanAttack(player))
        {
            AttackBehavior();
        }
        else if (timeSinceLastSawPlayer < suspicionTime)
        {
            SuspicionBehavior();
        }
        else
        {
            PatrolBehavior();

        }

        UpdateTimers();

    }

    private void PatrolBehavior()
    {
        Vector3 nextPosition = guardPosition;

        if (patrolPath != null)
        {
            if (AtWaypoint())
            {
                timeSinceArriveAtWaypoint = 0;
                CycleWaypoint();
            }
            nextPosition = GetCurrentWaypoint();
        }

        if (timeSinceArriveAtWaypoint > waypointDwellTime)
        {
            mover.StartMoveAction(nextPosition, patrolSpeedFraction);
        }
        else
        {
            mover.Cancel();
        }

    }

    private void SuspicionBehavior()
    {
        mover.Cancel();
    }

}
public class Mover : MonoBehaviour, IAction
    {
        private Direction lastMovementDirection;
        private Vector2 lastDirection;
        public bool isMovingAnimationSet = false;
        [HideInInspector]
        public bool isIdling = true;

        private enum Direction
        {
            Left,
            Right,
            Up,
            Down,
            None
        }

        private void Update()
        {
            bool isDead = health.IsDead();
            rb.isKinematic = isDead;
            capsuleCollider.enabled = !isDead;
            Debug.Log(isIdling);
        }

        private void FixedUpdate()
        {
            if (rb != null)
            {
                rb.velocity = velocity;
            }
        }

        public void StartMoveAction(Vector2 destination, float speedFraction)
        {
            if (!isMovingAnimationSet)
            {
                Debug.Log("Start Moving");
                isIdling = false;
                isMovingAnimationSet = true;
                ChangeAnimation("Walk", GetLastDirection());
            }

            MoveTo(destination, speedFraction);
        }

        public void MoveTo(Vector2 destination, float speedFraction)
        {
            Vector2 currentPosition = transform.position;
            Vector2 direction = (destination - currentPosition).normalized;
            velocity = direction * maxSpeed * Mathf.Clamp01(speedFraction);

            Direction currentMovementDirection = GetMovementDirection(direction);

            if (currentMovementDirection != lastMovementDirection)
            {
                lastMovementDirection = currentMovementDirection;
                lastDirection = direction;
                Debug.Log("Moving To");
                ChangeAnimation("Walk", direction);
            }
        }

        public void Cancel()
        {
            velocity = Vector2.zero;

            if (!isIdling)
            {
                isIdling = true;
                isMovingAnimationSet = false;
                ChangeAnimation("Idle", GetLastDirection());
            }
        }

        public Vector2 GetLastDirection()
        {
            return lastDirection;
        }

        public bool IsMoving
        {
            get { return velocity != Vector2.zero; }
        }

    }

Sounds like a bug! Could be in the animation setup so always start there. If the animation does not respond to properties correctly, all the code in the world won’t fix it.

Once you’re convinced the underlying animation is set up properly, then move onto debugging the code itself.

By debugging you can find out exactly what your program is doing so you can fix it.

Use the above techniques to get the information you need in order to reason about what the problem is.

You can also use Debug.Log(...); statements to find out if any of your code is even running. Don’t assume it is.

Once you understand what the problem is, you may begin to reason about a solution to the problem.

It’s not the animation I’ve confirmed that step. It’s how the code is executing the animation. I’ve debugged for hours trying to figure out where this is messing up including setting breakpoints but I’ve yet to be able to pinpoint the exact issue. I’ll probably start stripping away logic and slowing introduce things back in.

Can you share the ChangeAnimation function?

It would probably help to put a Debug.Log statement in the ChangeAnimation function or just before every place this function is called to see if it is getting called at a time you do not expect. Perhaps something is calling this every frame and is causing the walk animation to restart constantly.

1 Like