IEnumerator Patrol()
    {
        while (true)
        {
            if ((startPoint.position.x - transform.position.x > 0 || enemyController2D.collisions.left) && !controlled && !animator.GetBool("PlayerInSight"))
            {
                setDestination(endPoint);
            }

            else if ((endPoint.position.x - transform.position.x < 0 || enemyController2D.collisions.right) && !controlled && !animator.GetBool("PlayerInSight"))
            {
                setDestination(startPoint);
            }

            if (ranged && !animator.GetBool("PlayerInSight") && !controlled && transform.position.x > startPoint.position.x && transform.position.x < endPoint.position.x)
            {
                RaycastHit2D hit = Physics2D.Raycast(new Vector2(weapon.pivot.position.x, transform.GetComponent <BoxCollider2D>().bounds.max.y + 0.01f), Vector2.up);
                if (hit && hit.collider.CompareTag(Tags.light))
                {
                    LightController lightController = hit.collider.gameObject.GetComponent <LightController>();
                    if (!lightController.lightStatus && !lightController.changingStatus && weapon.currentCharge > 0)
                    {
                        weapon.armTransform.rotation = Quaternion.Euler(0.0f, 0.0f, enemy.transform.localScale.x * 159.1f);
                        lightController.SwitchOnOff(weapon.transform);
                        weapon.StartCoroutine("TrailingEffectOn", lightController.switchTime);
                        weapon.StartCoroutine(weapon.LightningEffectOn(lightController.switchTime, true));
                        shootingLights = true;
                    }
                }
            }

            if (!controlled && !changingStatus)
            {
                //questo è il caso del return to patrol
                mDirection = (mDestination.position - transform.position);
                if (mDirection.y > 0.3f || isClimbing)
                {
                    float      closestLadder = 10000f;
                    GameObject ladder        = null;
                    foreach (Collider2D obj in Physics2D.OverlapCircleAll(transform.position, 100f))
                    {
                        if ((transform.position.y - startPoint.position.y) > 0)
                        {
                            if (((obj.CompareTag(Tags.ladder) && !obj.name.Contains("MidLadder")) || obj.CompareTag(Tags.baseLadder) || obj.CompareTag(Tags.topLadder)) && (obj.transform.position.y - boxCollider2D.bounds.min.y > -15))
                            {
                                if (Vector3.Distance(obj.transform.position, transform.position) < closestLadder)
                                {
                                    closestLadder = Vector3.Distance(obj.transform.position, transform.position);
                                    ladder        = obj.transform.gameObject;
                                }
                            }
                        }
                        else
                        {
                            if (((obj.CompareTag(Tags.ladder) && !obj.name.Contains("MidLadder")) || obj.CompareTag(Tags.baseLadder) || obj.CompareTag(Tags.topLadder)) && (obj.transform.position.y - boxCollider2D.bounds.min.y > 0 && obj.transform.position.y - boxCollider2D.bounds.min.y < 5))
                            {
                                if (Vector3.Distance(obj.transform.position, transform.position) < closestLadder)
                                {
                                    closestLadder = Vector3.Distance(obj.transform.position, transform.position);
                                    ladder        = obj.transform.gameObject;
                                }
                            }
                        }
                    }
                    if (ladder != null)
                    {
                        foreach (Collider2D obj in Physics2D.OverlapCircleAll(new Vector2(boxCollider2D.bounds.center.x, boxCollider2D.bounds.min.y), 0.1f))
                        {
                            if ((obj.CompareTag(Tags.ladder) && !obj.name.Contains("MidLadder")) || obj.CompareTag(Tags.baseLadder) || obj.CompareTag(Tags.topLadder))
                            {
                                isClimbing = true;
                                break;
                            }
                            else
                            {
                                isClimbing = false;
                            }
                        }

                        if (isClimbing)
                        {
                            if (!ladder.CompareTag(Tags.topLadder))
                            {
                                if (ladder.transform.parent.CompareTag(Tags.ladder))
                                {
                                    ladder = ladder.transform.parent.Find("TopLadder").gameObject;
                                }
                                else
                                {
                                    ladder = ladder.transform.Find("TopLadder").gameObject;
                                }
                            }
                            mChaseTarget        = new Vector3(ladder.GetComponent <Collider2D>().bounds.center.x, ladder.GetComponent <Collider2D>().bounds.max.y) + new Vector3(0, 10f, 0);
                            mDirection          = (mChaseTarget - transform.position);
                            mDirection.y       += 100;
                            transform.position += new Vector3(0f, 0.75f, 0f);
                        }
                        else
                        {
                            mChaseTarget = ladder.GetComponent <Collider2D>().bounds.center;
                            mDirection   = (mChaseTarget - transform.position);
                        }

                        if (ladder.transform.Find("TopLadder"))
                        {
                            ladder.transform.Find("TopLadder").gameObject.layer = 9;
                        }
                    }
                }
                else if (-mDirection.y > 0.3f)
                {
                    foreach (Collider2D obj in Physics2D.OverlapCircleAll(boxCollider2D.bounds.center, 0.1f))
                    {
                        if ((obj.CompareTag(Tags.ladder) && !obj.name.Contains("MidLadder")) || obj.CompareTag(Tags.baseLadder) || obj.CompareTag(Tags.topLadder))
                        {
                            obj.gameObject.layer = 9;
                            break;
                        }
                    }
                    mDirection = (startPosition - transform.position);
                }
                else if (!(transform.position.x > startPoint.position.x && transform.position.x < endPoint.position.x))
                {
                    mDirection = (startPosition - transform.position);
                }
                else
                {
                    mDirection = (mDestination.position - transform.position);
                    if (Mathf.Abs(mDirection.x) < 1)
                    {
                        mDirection.x += 0.03f * Mathf.Sign(mDirection.x);
                    }
                }

                if (shootingLights || gettingShoot)
                {
                    mDirection = Vector2.zero;
                }

                if (!changingStatus && player != null)
                {
                    if (InLineOfSight(player, sightRange) && GameObject.FindGameObjectWithTag(Tags.mainCamera).GetComponent <Collider2D>().bounds.Contains(transform.position + new Vector3(0, 0, -10)) && GameObject.FindGameObjectWithTag(Tags.mainCamera).GetComponent <Collider2D>().bounds.Contains(player.position + new Vector3(0, 0, -10)))
                    {
                        animator.SetBool("PlayerInSight", true);
                        playerInSight = true;
                        mChaseTarget  = player.position;
                    }
                }
                enemy.SetDirectionalInput(mDirection.normalized);
            }
            else if (changingStatus || enemy.controlling || gettingShoot)
            {
                enemy.SetDirectionalInput(Vector2.zero);
            }

            yield return(null);
        }
    }