示例#1
0
    /**********************************************************************************/
    // функция генерирует внутренности блока
    //
    // порядок генерации объектов:
    // - Здания
    // - Дороги
    // - Генерируемое окружение
    /**********************************************************************************/
    void GenerateBlockContent(GameObject block, BlockDescriptor descriptor, int x, int y)
    {
        // определяемся с ограничениями на соединение дорог
        RoadManager.GetInstance().SetRoadRulesToBlock(descriptor, x, y);


        // обновляем карту занятых и свободных клеток
        descriptor.UpdateFreeSpaceMap(SizeOfBlocks);


        // определяем тип блока для генерации
        Base.BLOCK_TYPE blockToGenerate = GetBlockTypeToGenerate();

        // олучаем настройки для данного блока из библиотеки блоков
        BlockSettings settingsForGeneration = BlockLibrary.GetInstance().GetBlockSettings(blockToGenerate);

        // устанавливаем здания
        // для это выбираем его(их) из имеющейся коллекции
        List <GameObject> toInstantiateCollection = GetBuildingToInstance(settingsForGeneration);

        foreach (GameObject toInstantiate in toInstantiateCollection)
        {
            // получаем контроллер у объекта шаблона, он нам потребуется для определения размеров здания
            BuildingController bcOfPattern = toInstantiate.GetComponent <BuildingController>();

            // пробуем установить здание в блок
            bool success  = false;
            int  attempts = 10;
            while (!success && attempts > 0)
            {
                int xBuildingSize = bcOfPattern.XBuildingSize;
                int yBuildingSize = bcOfPattern.YBuildingSize;


                int xCorToPlace = Random.Range(0, (descriptor.xSize * SizeOfBlocks) - xBuildingSize + 1);
                int yCorToPlace = Random.Range(0, (descriptor.ySize * SizeOfBlocks) - yBuildingSize + 1);

                bool isPossible = true;

                // проверяем тушку здания
                for (int xCorToCheck = xCorToPlace; xCorToCheck < xCorToPlace + xBuildingSize; xCorToCheck++)
                {
                    for (int yCorToCheck = yCorToPlace; yCorToCheck < yCorToPlace + yBuildingSize; yCorToCheck++)
                    {
                        if (descriptor.FreeSpaceMap[xCorToCheck, yCorToCheck] != true)
                        {
                            isPossible = false;
                        }
                    }
                }

                // проверяем точку выхода из здания
                if (isPossible)
                {
                    Point roadPoint = new Point(xCorToPlace, yCorToPlace) + bcOfPattern.RoadPoint;
                    if (roadPoint.x < 0 || roadPoint.y < 0 || roadPoint.x >= SizeOfBlocks || roadPoint.y >= SizeOfBlocks)
                    {
                        isPossible = false;
                    }
                    else
                    {
                        if (descriptor.FreeSpaceMap[roadPoint.x, roadPoint.y] != true)
                        {
                            isPossible = false;
                        }
                    }
                }

                // если получилось подобрать координаты, устанавливаем новое здание в позицию и выходим из цикла
                if (isPossible)
                {
                    // правильные координаты будут выставлены несколькими шагами дальше через localPosition
                    GameObject instance = Instantiate(toInstantiate, new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity) as GameObject;

                    // устанавливаем в родителя
                    instance.transform.SetParent(block.transform);
                    instance.transform.localPosition = new Vector3((float)(xCorToPlace + xBuildingSize / 2) * SizeOfCell,
                                                                   (float)(yCorToPlace + yBuildingSize / 2) * SizeOfCell, 0.0f);

                    // сохраняем ссылку на все сгенерированные здания
                    descriptor.Buildings.Add(instance);

                    // обновляем карту свободных клеток в блоке
                    descriptor.UpdateFreeSpaceMap(SizeOfBlocks);

                    success = true;
                }

                // уменьшаем оставшееся кол-во попыток
                attempts--;
            }
        }


        // достраиваем дороги
        RoadManager.GetInstance().BuildRoadInBlock(descriptor, x, y, SizeOfBlocks);

        // генерируем прочие декоротивные и не только объекты
        GenerateBlockEnviroment(block, descriptor, settingsForGeneration, SizeOfBlocks);
    }
示例#2
0
    /**********************************************************************************/
    // функция генерирует наполнитель для блока
    // вызывается после генерации зданий и дорог, когда ограничители по пространству уже определены
    //
    /**********************************************************************************/
    void GenerateBlockEnviroment(GameObject block, BlockDescriptor descriptor, BlockSettings settings, int SizeOfBlocks)
    {
        int numberOfGeneratedObject         = settings.NumOfEnvElements;
        List <GameObject> applicableObjects = new List <GameObject>();

        foreach (GeneratedEnvironmentCtr.ENV_TYPE objType in settings.EnvTypes)
        {
            // формирование списка применимых для данного блока элементов
            foreach (GameObject generatedEnvObj in GeneratedEnvCollection)
            {
                // получаем контроллер и проверяем его тип
                GeneratedEnvironmentCtr ctr = generatedEnvObj.GetComponent <GeneratedEnvironmentCtr>();
                if (ctr == null)
                {
                    Debug.LogError("Wrong GeneratedEnvironmentCtr! is Null!");
                    return;
                }

                if (ctr.TYPE == objType)
                {
                    applicableObjects.Add(generatedEnvObj);
                }
            }
        }

        if (applicableObjects.Count == 0)
        {
            Debug.LogWarning("We have no enviroment items for: " + settings.EnvTypes.ToString() + ";  types");
            return;
        }

        // выбираем рандомные элементы из получившегося набора и используем их для заполнения блока
        // обновляем карту пространства
        for (int itemN = 0; itemN < numberOfGeneratedObject; itemN++)
        {
            GameObject envItemToInstance = applicableObjects[Random.Range(0, applicableObjects.Count)];

            bool generatingSuccess = false;
            bool weHaveFreeSpace   = true;
            while (!generatingSuccess && weHaveFreeSpace)
            {
                // состовляем коллекцию свободных точек
                List <Point> freeSpacePoints = new List <Point>();
                for (int x = 0; x < SizeOfBlocks; x++)
                {
                    for (int y = 0; y < SizeOfBlocks; y++)
                    {
                        if (descriptor.FreeSpaceMap[x, y] == true)
                        {
                            freeSpacePoints.Add(new Point(x, y));
                        }
                    }
                }

                // проверяем наличие свободного пространства
                if (freeSpacePoints.Count == 0)
                {
                    weHaveFreeSpace = false;
                    continue;
                }

                // выбираем случайную точку из свободных и устанавливаем туда элемент окружения
                Point randomFreePosition = freeSpacePoints[Random.Range(0, freeSpacePoints.Count)];
                int   xPos = randomFreePosition.x;
                int   yPos = randomFreePosition.y;


                // правильные координаты будут выставлены несколькими шагами дальше через localPosition
                GameObject instance = Instantiate(envItemToInstance, new Vector3(0.0f, 0.0f, 0.0f), Quaternion.identity) as GameObject;

                GeneratedEnvironmentCtr gec = instance.GetComponent <GeneratedEnvironmentCtr>();

                // устанавливаем в родителя ( TODO: без учёта размера генерируемого элемента)
                instance.transform.SetParent(block.transform);
                instance.transform.localPosition = new Vector3(((float)(xPos) + ((float)gec.SIZE) / 2) * SizeOfCell,
                                                               ((float)(yPos) + ((float)gec.SIZE) / 2) * SizeOfCell, 0.0f);

                // сохраняем локальные координаты
                gec.POSITION = new Point(xPos, yPos);

                // сохраняем ссылку на все сгенерированные элементы окружения
                descriptor.Enviroment.Add(instance);

                // обновляем карту свободных клеток в блоке
                descriptor.UpdateFreeSpaceMap(SizeOfBlocks);

                generatingSuccess = true;
            }
        }
    }
示例#3
0
    /**********************************************************************************/
    // функция ответсвенная за генерацию блоков
    //
    /**********************************************************************************/
    void GenerateBlocks(int xSize, int ySize)
    {
        // проверяем соответствие размера карты и блоков, они должны быть кратными
        if (MapSizeX % SizeOfBlocks != 0 || MapSizeY % SizeOfBlocks != 0)
        {
            Debug.LogError("MapGenerator::GenerateBlocks size of map or size of blocks is wrong!");
            return;
        }

        // шанс использования предопределённого блока
        // вынести в настройки (?)
        // ! НА ТЕКУЩИЙ МОМЕНТ ФУНКЦИОНАЛ ОТКЛЮЧЁН !
        // требуется коллекция предопределённых блоков для использования
        float chanseOfSpecialBloks = -0.1f;


        int xMapSizeInBlocks = MapSizeX / SizeOfBlocks;
        int yMapSizeInBlocks = MapSizeY / SizeOfBlocks;

        // проходимся по всей карте и заполняем её блоками
        for (int x = 0; x < xMapSizeInBlocks; x++)
        {
            for (int y = 0; y < yMapSizeInBlocks; y++)
            {
                // определяем, используем ли мы специальный блок или генерируемый
                float      chanse        = Random.Range(0.0f, 1.0f);
                bool       isGenerated   = false;
                GameObject toInstantiate = null;

                // выбираем блок для "постройки"
                if (chanse <= chanseOfSpecialBloks)
                {
                    int  attempts = 5;
                    bool succsecc = false;

                    while (attempts > 0 && !succsecc)
                    {
                        toInstantiate = BaseBlockCollection[Random.Range(0, BaseBlockCollection.Length)];
                        succsecc      = RoadManager.GetInstance().IsBlockOk(toInstantiate, x, y);
                        attempts--;
                    }

                    // если не получилось выбрать блок - переключаемся на генерацию
                    if (!succsecc)
                    {
                        toInstantiate = EmptyBlock;
                        isGenerated   = true;
                    }
                }
                // генерируем блок, для этого используется пустая болванка
                else
                {
                    toInstantiate = EmptyBlock;
                    isGenerated   = true;
                }


                // проверяем возможность установки
                // если нет - уходим на следующую итерацию
                BlockDescriptor descriptor = toInstantiate.GetComponent <BlockDescriptor>();

                if (!IsPositionFree(x, y, descriptor))
                {
                    continue;
                }

                // создаём новый экземпляр блока
                GameObject instance = Instantiate(toInstantiate, new Vector3((float)x * SizeOfCell * SizeOfBlocks, (float)y * SizeOfCell * SizeOfBlocks, 0.0f), Quaternion.identity) as GameObject;

                // устанавливаем в родителя
                instance.transform.SetParent(BuildingCollector.transform);

                // выполняем окончательную установку и настройку блока
                bool res = PlaceBlockAtPosition(instance, x, y);
                if (res == false)
                {
                    Debug.LogError("Somothing is wrong with block place!");
                }

                BlockDescriptor instDescriptor = instance.GetComponent <BlockDescriptor>();

                if (isGenerated)
                {
                    // генерируем внутярнку блока
                    // объекты, дороги
                    GenerateBlockContent(instance, instDescriptor, x, y);
                }
                else
                {
                    instDescriptor.UpdateFreeSpaceMap(SizeOfBlocks);
                    // обновляем правила дорог
                    RoadManager.GetInstance().UpdateRulesForBlock(x, y, instDescriptor.RoadConnections);
                }

                PathFinder.GetInstance().ApplyBlockMapData(x, y, instDescriptor);
            }
        }
    }