private void OnTriggerStay(Collider other)
    {
        if (_stateMachine.Health.IsDead)
        {
            return;
        }

        bool enemyOrPlayerThreatInSight = false;

        // This is for potential threats
        if (other.CompareTag("Player") || other.CompareTag("Enemy"))
        {
            if (_angryAt.Count == 0)
            {
                goto NotAngryAtAnyoneInSight;
            }

            // First check if we are angry at the potential target
            GameObject potentialTargetObject = _angryAt.Find(potentialTarget => potentialTarget == other.gameObject);
            if (potentialTargetObject == null)
            {
                goto NotAngryAtAnyoneInSight;
            }

            // If we are already seeing a player or enemy and the target we just saw is a different one, then we don't do anything
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.TargetTransform.gameObject != other.gameObject &&
                (_stateMachine.CurrentTarget.Type == AITargetType.Player || _stateMachine.CurrentTarget.Type == AITargetType.Enemy))
            {
                return;
            }

            // At this point, we are only interacting with either the target that we already have as a target or a new one (since we don't have a target at all)


            RaycastHit hitInfo;
            if (Physics.Raycast(transform.position, (other.transform.position + Vector3.up) - transform.position, out hitInfo, _sphereCollider.radius, _seeablesMask))
            {
                if (hitInfo.transform.gameObject == other.gameObject)
                {
                    float angle = Vector3.Angle(transform.forward, (other.transform.position + Vector3.up) - transform.position);
                    if (angle <= _fieldOfView)
                    {
                        _stateMachine.SetTarget(other.transform, AITargetType.Player);
                        enemyOrPlayerThreatInSight = true;
                    }
                }
            }

            // Resetting target for when the player or the enemy is inside the scanner collider but not inside the field of view
            // If we were seeing the player or the enemy and no longer see him, then we reset the target after the tolerance time
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.Player && !enemyOrPlayerThreatInSight)
            {
                _targetOutOfSightTime += Time.deltaTime;

                if (_targetOutOfSightTime >= _targetOutOfSightTolerance)
                {
                    _targetOutOfSightTime = 0f;
                    _stateMachine.ResetTarget();
                }
            }
        }

        if (enemyOrPlayerThreatInSight)
        {
            return;
        }

NotAngryAtAnyoneInSight:

        if (other.CompareTag("AIVehicleDetector") &&
            (_stateMachine.CurrentTarget == null || _stateMachine.CurrentTarget.Type != AITargetType.Vehicle) &&
            _stateMachine.CurrentState.GetStateType() != AIState.AIStateType.Vehicle)
        {
            InteractiveVehicle interactiveVehicle = other.GetComponent <InteractiveVehicle>();
            if (interactiveVehicle != null && !interactiveVehicle.Occupied)
            {
                AIStateVehicle aiStateDriving = (AIStateVehicle)(_stateMachine.GetState(AIState.AIStateType.Vehicle));
                if ((aiStateDriving.WantToDrive && interactiveVehicle.DriverSeat) || (aiStateDriving.WantToBePassenger && !interactiveVehicle.DriverSeat))
                {
                    _stateMachine.SetTarget(other.transform, AITargetType.Vehicle);
                    return;
                }
            }
        }

        if (other.CompareTag("Chair") &&
            (_stateMachine.CurrentTarget == null || _stateMachine.CurrentTarget.Type != AITargetType.Chair) &&
            _stateMachine.CurrentState.GetStateType() != AIState.AIStateType.Sitting)
        {
            InteractiveChair interactiveChair = other.GetComponent <InteractiveChair>();
            if (interactiveChair != null && !interactiveChair.IsOccupied)
            {
                AIStateSitting aiStateDriving = (AIStateSitting)(_stateMachine.GetState(AIState.AIStateType.Sitting));
                if (aiStateDriving.IsTired)
                {
                    _stateMachine.SetTarget(other.transform, AITargetType.Chair);
                    return;
                }
            }
        }

        // For social Interaction
        if (other.CompareTag("Enemy"))
        {
            // if we are already interacting socially, then there is nothing to do here
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.Friend)
            {
                return;
            }

            AIStateMachine otherStateMachine = other.GetComponent <AIStateMachine>();

            AIStateSocialInteraction mySocialInteractionState     = (AIStateSocialInteraction)(_stateMachine.GetState(AIState.AIStateType.SocialInteraction));
            AIStatePursuit           myPursuitState               = (AIStatePursuit)(_stateMachine.GetState(AIState.AIStateType.Pursuit));
            AIStateSocialInteraction friendSocialInteractionState = (AIStateSocialInteraction)(otherStateMachine.GetState(AIState.AIStateType.SocialInteraction));
            AIStatePursuit           friendPursuitState           = (AIStatePursuit)(otherStateMachine.GetState(AIState.AIStateType.Pursuit));
            if (mySocialInteractionState.IsFeelingLonely && friendSocialInteractionState.IsFeelingLonely &&
                !otherStateMachine.Health.IsDead)
            {
                // If the friend hasn't gotten into social mode yet by setting a target of type friend, then we are the ones who are going to be making the first move
                if (otherStateMachine.CurrentTarget == null ||
                    otherStateMachine.CurrentTarget.Type == AITargetType.None ||
                    otherStateMachine.CurrentTarget.Type == AITargetType.NavigationPoint ||
                    otherStateMachine.CurrentTarget.Type == AITargetType.BoomBox)
                {
                    myPursuitState.ShouldMakeAMove = true;
                    mySocialInteractionState.FriendSocialInteraction = friendSocialInteractionState;
                    // We set our pursuit mode by setting a target
                    _stateMachine.SetTarget(other.transform, AITargetType.Friend);

                    // the friend should instantly get into social mode
                    friendSocialInteractionState.FriendSocialInteraction = mySocialInteractionState;
                    otherStateMachine.SetTarget(transform, AITargetType.Friend);
                    otherStateMachine.SwitchState(AIState.AIStateType.SocialInteraction);
                }
            }
        }

        if (other.CompareTag("BoomBox"))
        {
            // If we have a more important target: Another AI Agent as an enemy, a friend or a player, then we ignore the boombox
            if (_stateMachine.CurrentTarget != null &&
                (_stateMachine.CurrentTarget.Type == AITargetType.Player ||
                 _stateMachine.CurrentTarget.Type == AITargetType.Enemy ||
                 _stateMachine.CurrentTarget.Type == AITargetType.Friend))
            {
                return;
            }

            AIStateDancing aiStateDancing = (AIStateDancing)(_stateMachine.GetState(AIState.AIStateType.Dancing));
            if (aiStateDancing.IsHungry)
            {
                _stateMachine.SetTarget(other.transform, AITargetType.BoomBox);
            }
        }
    }
    public override AIStateType OnUpdate()
    {
        // Sometimes we are pusuing something but the target is null. We would like to still go to the last position of the target.
        if (_stateMachine.CurrentTarget == null)
        {
            if (_stateMachine.Agent.hasPath)
            {
                if (!_stateMachine.Agent.pathPending &&
                    (_stateMachine.Agent.remainingDistance <= _stateMachine.Agent.stoppingDistance ||
                     _stateMachine.Agent.isPathStale))
                {
                    return(AIStateType.Alert);
                }
            }
            else
            {
                return(AIStateType.Alert);
            }
        }

        // If we can't reach the target, we go into hurdle mode
        if (_stateMachine.Agent.isPathStale)
        {
            return(AIStateType.Hurdle);
        }

        PeriodicDestination();

        float stoppingDistance = GetStoppingDistance(_stateMachine.Agent.stoppingDistance);

        if (_stateMachine.Agent.remainingDistance <= stoppingDistance &&
            !_stateMachine.Agent.isPathStale)
        {
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.Player &&
                Vector3.Distance(transform.position, _stateMachine.CurrentTarget.TargetTransform.position) <= _stateMachine.Agent.stoppingDistance)
            {
                // We go into attack mode
                return(AIStateType.Attack);
            }
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.Sound)
            {
                // We reset the target and go into sound mode if it's a sound
                _stateMachine.ResetTarget();
                return(AIStateType.Alert);
            }
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.BoomBox)
            {
                return(AIStateType.Dancing);
            }
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.Friend)
            {
                return(AIStateType.SocialInteraction);
            }
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.Vehicle)
            {
                return(AIStateType.Vehicle);
            }
            if (_stateMachine.CurrentTarget != null && _stateMachine.CurrentTarget.Type == AITargetType.Chair)
            {
                // We need to check if the chair is already occupied
                AIStateSitting   aiStateSitting    = GetComponent <AIStateSitting>();
                InteractiveChair _interactiveChair = _stateMachine.CurrentTarget.TargetTransform.GetComponent <InteractiveChair>();
                if (aiStateSitting != null && !_interactiveChair.IsOccupied)
                {
                    return(AIStateType.Sitting);
                }
                else
                {
                    _stateMachine.ResetTarget();
                    _stateMachine.Agent.ResetPath();
                }
            }
        }

        LookAtObjective();

        HandleAnimator();

        return(AIStateType.Pursuit);
    }