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);
            }
        }
    }
    private void OnTriggerStay(Collider other)
    {
        bool playerInSight = false;
        bool foodInSight   = false;

        if (other.CompareTag("Player") || other.CompareTag("Food"))
        {
            RaycastHit hitInfo;
            float      upCoeffecient = other.CompareTag("Player") ? 1 : 0;
            Debug.DrawRay(transform.position, (other.transform.position + Vector3.up * upCoeffecient) - transform.position, Color.red);
            if (Physics.Raycast(transform.position, (other.transform.position + Vector3.up * upCoeffecient) - transform.position, out hitInfo, _sphereCollider.radius, LayerMask.GetMask("EnemyThreat", "Default", "Gravel", "Wood", "Grass", "Metal")))
            {
                if (hitInfo.transform.gameObject == other.gameObject)
                {
                    float angle = Vector3.Angle(transform.forward, (other.transform.position + Vector3.up * upCoeffecient) - transform.position);
                    if (angle <= _fieldOfView)
                    {
                        // We have the player directly in sight
                        if (other.CompareTag("Player"))
                        {
                            _stateMachine.SetTarget(other.transform, AITargetType.Player);
                            playerInSight = true;
                        }

                        if (other.CompareTag("Food"))
                        {
                            // We only start feeding when there is no other target in sight
                            // or when the target is neither a player neither a sound
                            if (_stateMachine.CurrentTarget == null ||
                                (_stateMachine.CurrentTarget != null &&
                                 _stateMachine.CurrentTarget.Type != AITargetType.Player &&
                                 _stateMachine.CurrentTarget.Type != AITargetType.Sound))
                            {
                                // We need to check if we are hungry
                                AIState state = _stateMachine.GetState(AIState.AIStateType.Feeding);
                                if (state != null)
                                {
                                    AIStateFeeding stateFeeding = (AIStateFeeding)state;
                                    if (stateFeeding.IsHungry)
                                    {
                                        _stateMachine.SetTarget(other.transform, AITargetType.Food);
                                        foodInSight = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        // We shouldn't detect our own sound
        if (other.CompareTag("Sound") && _stateMachine.AISoundManager.SoundEmitter.gameObject != other.gameObject)
        {
            if (_stateMachine.CurrentTarget == null ||
                _stateMachine.CurrentTarget != null &&
                (_stateMachine.CurrentTarget.Type == AITargetType.Food || _stateMachine.CurrentTarget.Type == AITargetType.NavigationPoint ||
                 _stateMachine.CurrentTarget.Type == AITargetType.None))
            {
                _stateMachine.SetTarget(other.transform, AITargetType.Sound);
            }
        }

        if (_stateMachine.CurrentTarget != null)
        {
            // If we were seeing the player and no longer see him, then we reset the target
            if (other.CompareTag("Player") && !playerInSight && _stateMachine.CurrentTarget.Type == AITargetType.Player)
            {
                _stateMachine.ResetTarget();
            }

            // If we aren't seeing the player nor are we seeing the food and the previous target was food, then we reset the target
            // Food is the least prioritary out of all targets
            if (other.CompareTag("Food") && !foodInSight && _stateMachine.CurrentTarget.Type == AITargetType.Food)
            {
                _stateMachine.ResetTarget();
            }
        }
    }