void SetExits(bool test = false)
    {
        int i = 0;

        if (numExits > 0 && hasFirstExit == true)
        {
            usableExits.Add(exits[0]);
            i++;
        }

        ProceduralDungeonGenerator.ExitDirection new_dir = new ProceduralDungeonGenerator.ExitDirection();

        for (; i < numExits; i++)
        {
            ExitDirectionPoint temp = new ExitDirectionPoint();
            do
            {
                new_dir = (ProceduralDungeonGenerator.ExitDirection)Random.Range(0, 4);
            } while (IsAlreadyExitDirection(new_dir) == true);


            temp = GetExitInfo(new_dir);
            if (temp != null)
            {
                usableExits.Add(temp);
            }
        }
    }
    void PrintExitDoor(ProceduralDungeonGenerator.ExitDirection type)
    {
        ExitDirectionPoint exitP = GetExitByDir(type);

        if (exitP == null)
        {
            return;
        }

        Vector2    posInstantiate = Vector2.zero;
        GameObject go             = null;

        switch (exitP.dir)
        {
        case ProceduralDungeonGenerator.ExitDirection.LEFT_EXIT:
            posInstantiate.x = _x_pos + 0.01f;
            posInstantiate.y = _y_pos + (_tileheight * 0.5f) - 0.5f + 0.01f;

            go = ProceduralDungeonGenerator.mapGenerator.InstantiateGO(ProceduralDungeonGenerator.mapGenerator.doorPrefabVertical, Room_Go.transform);

            FlipDoorTiles(go, false, true);
            go.transform.localPosition = posInstantiate;
            break;

        case ProceduralDungeonGenerator.ExitDirection.RIGHT_EXIT:
            posInstantiate.x = _x_pos + _tilewidth - 1.0f + 0.01f;
            posInstantiate.y = _y_pos + (_tileheight * 0.5f) - 0.5f + 0.01f;

            go = ProceduralDungeonGenerator.mapGenerator.InstantiateGO(ProceduralDungeonGenerator.mapGenerator.doorPrefabVertical, Room_Go.transform);

            go.transform.localPosition = posInstantiate;
            break;

        case ProceduralDungeonGenerator.ExitDirection.DOWN_EXIT:
            posInstantiate.x = _x_pos + (_tilewidth * 0.5f) - 0.5f;;
            posInstantiate.y = _y_pos;

            go = ProceduralDungeonGenerator.mapGenerator.InstantiateGO(ProceduralDungeonGenerator.mapGenerator.doorPrefabHorizontal, Room_Go.transform);

            FlipDoorTiles(go, false, true);
            go.transform.localPosition = posInstantiate;
            break;

        case ProceduralDungeonGenerator.ExitDirection.UP_EXIT:
            posInstantiate.x = _x_pos + (_tilewidth * 0.5f) - 0.5f;;
            posInstantiate.y = _y_pos + _tileheight - 1.0f;

            go = ProceduralDungeonGenerator.mapGenerator.InstantiateGO(ProceduralDungeonGenerator.mapGenerator.doorPrefabHorizontal, Room_Go.transform);

            go.transform.localPosition = posInstantiate;
            break;
        }


        ProceduralDungeonGenerator.mapGenerator.myDoors.Add(go);
    }
    void ComprovationDown(bool noNeedComp = false)
    {
        Vector3Int downExit = new Vector3Int(_x_pos, _y_pos - _tileheight, 0);

        if (!ProceduralDungeonGenerator.mapGenerator.PointIsInsideAnyRoom(grid.CellToWorld(downExit)) || noNeedComp)
        {
            ExitDirectionPoint temp_down = new ExitDirectionPoint();
            temp_down.dir              = ProceduralDungeonGenerator.ExitDirection.DOWN_EXIT;
            temp_down.nextRoomPos      = downExit;
            temp_down.needRoomCreation = !noNeedComp;
            exits.Add(temp_down);
        }
    }
    void ComprovationUp(bool noNeedComp = false)
    {
        Vector3Int upExit = new Vector3Int(_x_pos, _y_pos + _tileheight, 0);

        if (!ProceduralDungeonGenerator.mapGenerator.PointIsInsideAnyRoom(grid.CellToWorld(upExit)) || noNeedComp)
        {
            ExitDirectionPoint temp_up = new ExitDirectionPoint();
            temp_up.dir              = ProceduralDungeonGenerator.ExitDirection.UP_EXIT;
            temp_up.nextRoomPos      = upExit;
            temp_up.needRoomCreation = !noNeedComp;
            exits.Add(temp_up);
        }
    }
    void ComprovationLeft(bool noNeedComp = false)
    {
        Vector3Int leftExit = new Vector3Int(_x_pos - _tilewidth, _y_pos, 0);

        if (!ProceduralDungeonGenerator.mapGenerator.PointIsInsideAnyRoom(grid.CellToWorld(leftExit)) || noNeedComp)
        {
            ExitDirectionPoint temp_left = new ExitDirectionPoint();
            temp_left.dir              = ProceduralDungeonGenerator.ExitDirection.LEFT_EXIT;
            temp_left.nextRoomPos      = leftExit;
            temp_left.needRoomCreation = !noNeedComp;
            exits.Add(temp_left);
        }
    }
    ExitDirectionPoint GetExitInfoUsable(ProceduralDungeonGenerator.ExitDirection mydir)
    {
        ExitDirectionPoint temp = null;

        for (int i = 0; i < usableExits.Count; i++)
        {
            if (usableExits[i] != null)
            {
                if (usableExits[i].dir == mydir)
                {
                    temp = usableExits[i];
                }
            }
        }

        return(temp);
    }
    void AddRightColliders()
    {
        ExitDirectionPoint exitTemp = GetExitInfoUsable(ProceduralDungeonGenerator.ExitDirection.RIGHT_EXIT);
        bool isInsideRoom           = false;

        if (exitTemp != null)
        {
            isInsideRoom = ProceduralDungeonGenerator.mapGenerator.PointIsInsideAnyRoom(exitTemp.nextRoomPos);
        }

        if (IsAlreadyExitDirection(ProceduralDungeonGenerator.ExitDirection.RIGHT_EXIT) && countCollidersExits < numExits &&
            isInsideRoom && exitTemp.isUsed)
        {
            countCollidersExits++;

            colliderFinalColliders.Add(ProceduralDungeonGenerator.ExitDirection.RIGHT_EXIT);

            GameObject collider_right_go_1 = new GameObject();
            SetLayerAndTagWall(collider_right_go_1);
            collider_right_go_1.transform.position = new Vector3(_x_pos + (_tilewidth - 1), _y_pos + ((_tileheight / 5) - 0.5f));
            collider_right_go_1.transform.SetParent(Room_Go.transform);

            BoxCollider2D right_collider1 = collider_right_go_1.AddComponent <BoxCollider2D>();
            right_collider1.size = new Vector2(1, (_tileheight / 5) * 2);


            GameObject collider_right_go_2 = new GameObject();
            SetLayerAndTagWall(collider_right_go_2);
            collider_right_go_2.transform.position = new Vector3(_x_pos + (_tilewidth - 1), _y_pos + ((_tileheight / 5) * (5 - 1) - 0.5f));
            collider_right_go_2.transform.SetParent(Room_Go.transform);

            BoxCollider2D right_collider2 = collider_right_go_2.AddComponent <BoxCollider2D>();
            right_collider2.size = new Vector2(1, (_tileheight / 5) * 2);
        }
        else
        {
            GameObject collider_right_go = new GameObject();
            SetLayerAndTagWall(collider_right_go);
            collider_right_go.transform.position = new Vector3(_x_pos + (_tilewidth - 1), _y_pos + ((_tileheight * 0.5f) - 0.5f));
            collider_right_go.transform.SetParent(Room_Go.transform);

            BoxCollider2D right_collider = collider_right_go.AddComponent <BoxCollider2D>();
            right_collider.size = new Vector2(1, _tileheight);
        }
    }
    ExitDirectionPoint GetExitByDir(ProceduralDungeonGenerator.ExitDirection type)
    {
        ExitDirectionPoint ret = null;

        foreach (ExitDirectionPoint exit in usableExits)
        {
            if (exit == null)
            {
                continue;
            }

            if (exit.dir == type)
            {
                ret = exit;
                break;
            }
        }

        return(ret);
    }
    void GenerateRoomLastChildFirst(Procedural_Room room, int level)
    {
        Procedural_Room    creation_room;
        ExitDirectionPoint creation_point = new ExitDirectionPoint();

        count_rooms++;

        if (level + 1 == realDepth && !_AddBoss && _counterBoss == 0)
        {
            _AddBoss = true;
        }
        else if (level == realDepth * 0.5 && !_AddMiniBoss && _counterMiniBoss == 0)
        {
            _AddMiniBoss = true;
        }


        if (level == realDepth)
        {
            Vector3    posUpgrade = room.GetMiddlePositionRoom();
            GameObject go         = Instantiate(UpgradeObject);
            go.transform.position = posUpgrade;

            int it = FindInRooms(room);
            if (rooms[it].usableExits.Count > 0)
            {
                rooms[it].usableExits[0].isUsed = true;
            }
            return;
        }

        for (int i = 0; i < room.usableExits.Count; i++)
        {
            creation_point = room.usableExits[i];

            bool wantToCreate = creation_point.needRoomCreation;
            if (!wantToCreate)
            {
                int it = FindInRooms(room);
                rooms[it].usableExits[i].isUsed = true;
            }

            if (creation_point.needRoomCreation && !PointIsInsideAnyRoom(creation_point.nextRoomPos))
            {
                int it = FindInRooms(room);
                rooms[it].usableExits[i].isUsed = true;

                if (_AddBoss)
                {
                    _counterBoss++;
                }
                else if (_AddMiniBoss)
                {
                    _counterMiniBoss++;
                }

                creation_room = new Procedural_Room(creation_point.nextRoomPos.x, creation_point.nextRoomPos.y, tilesWidthRoom, tilesHeightRoom, count_rooms, OppositeDirection(creation_point.dir), level, _AddBoss, _AddMiniBoss);

                _AddBoss     = false;
                _AddMiniBoss = false;

                if (creation_room.wantToDraw)
                {
                    rooms.Add(creation_room);
                    GenerateRoomLastChildFirst(creation_room, level + 1);
                }
            }
        }
    }