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; }
}
}