Как сделать пещеры в юнити

Террейн в Unity 3D. Часть Вводная – для затравки. Создание лабиринтов и подземелий в Unity3D

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Террейн в Unity 3D… О нем можно рассказывать бесконечно долго, поэтому я начинаю публиковать цикл статей, посвященный созданию ландшафтов, еще называемых террейнами, в Unity3D, сторонних бесплатных программах для создания ландшафтов, 3D приложениях, в которых также можно создавать ландшафты для игровых движков Unity3D, Unreal Engine, Amazon lumberyard, CryEngine, Neoaxis 3d Engine и других.

В данной статье (являющейся вводной для серии статей — уроков по созданию террейнов) описывается создание пользовательских (“кастомных”) кистей для редактирования террейна в Unity3D, а также использующихся для создания в Unity 3D лабиринтов, подземелий, коридоров, пещер и живых изгородей.

Если вам понравился материал, размещенный на данном сайте, вы всегда можете отблагодарить автора сайта, сделав пожертвование на сумму, которая не утянет ваш кошелек, но поможет автору статей писать больше полезных уроков и статей, посвященных созданию игр и трехмерных моделей для них.

Создаем кисть для террейна Unity3D в графическом редакторе GIMP

Если вы хоть раз рисовали или редактировали изображения в Adobe Photoshop или GIMP, то должны знать, какую роль играют кисти и, наверняка, загрузили не одну кисть, чтобы облегчить себе работу в одном из этих графических редакторов. Так почему бы нам не создать свои кисти для Unity 3D, при помощи которых можно было бы в редакторе Unity3D редактировать ландшафт.

Кисти для редактирования террейна являются ничем иным, как изображением с прозрачным фоном, на котором черным цветом нанесен ваш шаблон будущей кисти. Создайте новый изображение (файл, холст, документ) в GIMP, для чего нажмите сочетание клавиш Ctrl+N, или выберите вкладку “File”, чтобы открыть меню работы с документом/файлом и выберите в открывшемся меню вкладку “New”. Установите размер изображения равным 512 на 512 пикслей (или 256 x 256 пикселей) в меню создания нового изображения. Разверните список расширенных настроек изображения “Advanced Options”, в котором для цветовой гаммы/режима цвета изображения “Color space”выберите “RGB” или градации серого “Greyscale”, а фон оставьте прозрачным, для чего выберите “Transparency” для параметра “Fill With” (Залить с помощью…).

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити На рисунке показан процесс создания нового изображения в GIMP под кисть для редактирования террейна в Unity3D.

Теперь выберите цвет, которым мы будем рисовать. Здесь действуют те же принципы, что и для карты высот: по сути, изображение для кисти, которое мы сейчас создаем, работает как карта высот, из которой даже можно создать террейн в Unity 3D, просто экспортировав ее, за тем лишь исключением, что вместо белого фона для определения самой низкой точки террейна, здесь используется прозрачный фон. Т.е. достаточно сохранить такую кисть с белым или серым фоном в формате RAW в градациях серого в восьмибитном (8бит/8 bit) или шестнадцатибитном (16 бит/16 bit) режиме (Color Mode/Color Space).

Как только вы завершите создание своей кисти, необходимо сохранить ее в формате PNG, поддерживающем прозрачный фон изображения. Назовите файл с кистью “brush_0.png

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити На рисунке показан процесс экспорта изображения в GIMP в формате PNG.

Осталось перенести созданное изображение кисти в Unity3D, чтобы начать изменять с ее помощью террейн в Unity 3D.

Импорт изображения кисти в Unity3D для редактирования террейна или создания нового красивого ландшафта в Unity3D

Одним из условий для того чтобы Unity увидел ваши кисти, является создание папки “Gizmos” в ассетах “Assets” проекта (окно “Project“). Вы можете создать папку гизмо “Gizmos” (на рисунке ниже отмечено оранжевым цветом) в ассетах Юнити “Assets” и импортировать в нее файлы, содержащие кисти (перетащить файлы с изображениями кистей из папки, в которой они хранятся на жестком диске или даже SSD вашего компьютера в созданную в ассетах папку “Gizmos”, как показано на рисунке ниже зеленым цветом). Вы также можете создать папку “Gizmos” на жестком диске своего компьютера, поместить в нее свои кисти, созданные в одном из графических редакторов – Photoshop или GIMP, и импортировать ее в ассеты “Assets”, например, Unity 3D путем простого перетаскивания (drag’n’drop/Drag-and-Drop) ее в окно с ассетами “Assets” Юнити.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити На рисунке показан процесс импорта в Unity 3D созданных кистей для редактирования террейна.

Как только вы импортируете созданные кисти в Unity3D, то они сразу же появятся во всех вкладках-инструментах, поддерживающих работу с кистями, в компоненте Terrain: “Raise/Lower Terrain”, “Paint Height”, “Smooth Height” и “Paint Texture”. Если этого не произошло, закройте Unity3D и откройте проект с террейном, куда вы импортировали кисти. Если кисти не появились, то читайте ниже.

Как вы можете видеть на рисунке выше, в инструментах редактирования ландшафта отобразились не все кисти, которые мы загрузили в Unity, а лишь первые три, которые были сохранены в файлах с именами “brush_0”, “brush_1”, “brush_2” (показано на рисунке выше бирюзовым цветом). А вот кисти “brush_4” и “brush_mg” (отмечены красным на рисунке выше) не воспринимаются по причине, описанной ниже.

Вторым условием для того, чтобы иметь возможность использовать ваши кисти, является правильное название кистей. Если вы назовете свою кисть “my-brush”, “brush-1”, “моя кисть”, “магическая кисть под террейн Unity3D” и т.д., то Unity, хотя и отобразит их в папке “Gizmos”, но не даст вам их использовать для изменения созданного террейна. Для того чтобы Unity “подхватил” созданные вами кисти, необходимо называть их следующим образом: “brush_0”, “brush_1”, “brush_2”, “brush_3” и так далее. Unity 3D не допускает начало именования кистей с единицы и если вы пропустите кисть с названием “brush_0” или удалите ее из папки “Gizmos”, то кисти с именами “brush_1”, “brush_2”, “brush_3” видны редактором террейна Unity 3D не будут. Также, если у вас в папке “Gizmos” будет присутствовать кисть с именем “brush_0”, “brush_1” и “brush_2”, но не будет кисти с именем “brush_3”, то если вы добавите в папку гизмо “Gizmos” кисть с именем “brush_4”, то кисть “brush_4” и все последующие “brush_5”, “brush_6”, “brush_7” и так далее (brush_N+1) видны не будут, хотя и будут отображаться в папке гизмо “Gizmos”.

Не обязательно удалять изображения импортированных кистей из проекта (папки “Gizmos”, содержащей гизмо/ штучки) и потом заново импортировать файлы кистей с измененными названиями, чтобы переименовать текстуры кистей и заново импортировать их в Unity. Вы всегда можете изменить название импортированных кистей в Unity3D на правильные. Если после изменения имен кистей в папке гизмо, они не появились в инструментах модифицирования ландшафта, то вы можете немного подождать, когда Unity идентифицирует их, либо перезагрузите проект, закрыв и заново открыв Unity 3D с вашим проектом. Все сказанное выше про названия кистей, касается и про название папки со штуковинами/ гизмо “Gizmos”.

После импорта изображений кистей в Unity 3D в папке гизмо “Gizmos” они представляют собой черный квадрат. Такие кисти будут работать (если вы сделали все, как описано в данном уроке), но вот определить какой кисти в редакторе ландшафта Юнити 3Д они соответствуют, будет затруднительно.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити На рисунке показан процесс изменения настроек импортированного изображения в Unity3D для создания изображению прозрачного фона в редакторе Unity.

Изменяем прозрачность изображения в Unity3D, чтобы оно отображалось в редакторе Unity3D с прозрачным фоном

Если вы хотите, чтобы в папке гизмо отображалась миниатюра изображения кисти, как, например, они отображаются в папках Windows, чтобы можно было идентифицировать, какая кисть в инструментах террейн в Unity 3D какому рисунку соответствует, то вы можете щелкнуть (“кликнуть”) на изображении кисти в папке гизмо “Gizmo”, и в открывшемся меню настройки изображения (настроек импорта изображений) в окне Инспектора (“Inspector”) изменить настройки изображения, поставив галочку (флаг) напротив параметра “Alpha is Transparent”, чтобы указать движку Unity3D, что у данного изображения – прозрачный фон, после чего нажать кнопку “Apply”, чтобы применить произведенные изменения. Если вы забудете применить сделанные изменения в меню настройки текстуры/изображения кисти, то при выходе из меню настройки импортированного изображения/текстуры, например, при выборе другого изображения, 3D объекта, скрипта (C# или Javascript/Unityscript) или террейна, Unity 3D напомнит вам о совершенных модификациях текстуры и откроет диалоговое окно “Unapplied import settings for ‘Assets/Gizmos/…’”, в котором предложит принять (“Apply”) или отменить (“Revert”) сделанные вами изменения для установок импорта текстуры/изображения.

Теперь вы можете рисовать кистями, которые создали сами.

Собственно… Террейн в Unity 3D. Создание лабиринта — живой изгороди или пещер и корридоров подземелий в Unity3D

При помощи кистей можно создавать не только горный, скалистый ландшафт, плато и другие элементы и формы, которые может принимать террейн в Unity 3D, но и лабиринты из живых изгородей, или подземной пещеры. Чтобы создать свой лабиринт или катакомбы, достаточно лишь нарисовать несколько кистей, соответствующих участкам лабиринта, или использовать в качестве кистей найденные в Интернете и загруженные карты лабиринтов (желательно, но не обязательно, в черно-белом варианте), либо использовать генератор подземелий, пещер или лабиринтов. Вы же не раз встречали в газетах или журналах, особенно детских журналах, задание найти выход из лабиринта, например, проведя по нему ручкой или карандашом? Так вот, один клик кистью, созданной из такой картинки, на террейне и уровень готов. Или часть уровня, поскольку вы можете создать несколько кистей, чтобы иметь возможность собирать уровень из “модулей”, где в качестве модулей будут использоваться кисти. Останется лишь раскрасить получившийся уровень по вашему усмотрению.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити На рисунке показан лабиринт, созданный через террейн в Unity 3D при помощи всего одной кисти для редактора ландшафта Юнити

На рисунке выше показан лабиринт — живая изгородь, созданный в Unity 3D при помощи редактора ландшафта. В данном случае была использована всего одна кисть для придания формы, которую может принимать террейн в Unity 3D. Также была использована одна стандартная круглая кисть в совокупности с тремя текстурами для раскрашивания террейна. К каждая текстура использовалась вместе с соответствующей ей картой нормалей.

Понравилась статья? Поддержи автора статьи!

Источник

Создание roguelike в Unity с нуля: генератор подземелий

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

На этот раз мы погрузимся в реализацию алгоритма генератора подземелий. В прошлой статье мы создали первую комнату, а теперь сгенерируем остальной уровень подземелья.

Но прежде чем мы начнём, я бы хотел исправить ошибку из предыдущего поста. На самом деле, за последние недели я научился кое-чему новому, из-за чего часть проделанной мной работы устарела, и я хочу рассказать об этом.

Помните созданный нами класс Position? Вообще-то в Unity уже имеется встроенный класс, выполняющий точно такие же функции, но с немного более качественным управлением — его проще объявлять и обрабатывать. Этот класс называется Vector2Int. Поэтому перед началом мы удалим из MapManager.cs класс Position и заменим каждую переменную Position на переменную Vector2Int.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Этап 7 — генерация комнаты/коридора

Мы начнём с небольшого изменения созданной в прошлый раз функции FirstRoom(). Вместо создания другой функции для генерации всех остальных элементов карты и дублирования кучи кода, мы просто преобразуем эту функцию, превратив её в обобщённую GenerateFeature(). Поэтому изменим имя с FirstRoom на GenerateFeature.

Теперь нам нужно будет передавать этой функции параметры. Во-первых функции нужно знать, какой элемент она генерирует — комнату или коридор. Мы можем просто передать строку с именем type. Далее функции нужно знать начальную точку элемента, то есть из какой стены она исходит (потому что мы всегда создаём новый элемент из стены более старого элемента), и для этого достаточно передачи в качестве аргумента Wall. Наконец, первая создаваемая комната имеет особые характеристики, поэтому нам нужна необязательная переменная bool, сообщающая, является ли элемент первой комнатой. По умолчанию она имеет значение false: bool isFirst = false. Итак заголовок функции сменится с этого:

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Отлично. Следующим шагом будет изменение способа вычисления ширины и высоты элемента. Пока мы вычисляем их, получая случайное значение между значениями min и max высоты и ширины комнат — для комнат это подходит идеально, но не будет работать для коридоров. Итак, пока у нас имеется следующее:

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Но коридоры будут иметь постоянный размер 3 в ширину или высоту, в зависимости от ориентации. Поэтому нам нужно проверять, чем является элемент — комнатой или коридором, а потом выполнять соответствующие вычисления.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Итак. мы проверяем, является ли элемент комнатой. Если да, то мы делаем так же, как и раньше
— получаем случайное число в интервале между min и max высоты и ширины. Но теперь в else того же if нужно сделать нечто немного иное. Нам нужно проверить ориентацию коридора. К счастью, при генерации стены мы сохраняем информацию о том, в какую сторону она направлена, поэтому используем её для получения ориентации коридора.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Но мы пока не объявили переменную minCorridorLength. Нужно вернуться к объявлениям переменных и объявить её, прямо над maxCorridorLength.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Теперь вернёмся к нашим условным операторам switch. Что мы здесь делаем: получаем значение направления стены, то есть, куда смотрит стена, из которой будет идти коридор. Направление может иметь всего четыре возможных значения: South, North, West и East. В случае South и North коридор будет иметь ширину 3 (две стены и пол посередине) и переменную высоту (длину). Для West и East всё будет наоборот: высота будет постоянно равна 3, а ширина иметь переменную длину. Итак, давайте сделаем это.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Здорово. И на этом мы закончили с определением размера нового элемента. Теперь нужно решить, куда его помещать. Первую комнату мы расположили в случайное место в пределах пороговых значений относительно центра карты.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Но для всех остальных элементов это не сработает. Они должны начинаться рядом со случайной точкой стены, из которой генерируется элемент. Поэтому давайте изменим код. Во-первых, нам нужно проверить, является ли элемент первой комнатой. Если это первая комната, то мы определяем начальные точки так же, как и ранее — как половину ширины и высоты карты.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

В else если элемент не является первой комнатой, то мы получаем случайную точку на стене, из которой генерируется элемент. Во-первых, мы должны проверить, имеет ли стена размер 3 (это будет означать, что она является конечной точкой коридора), и если это так, то всегда будет выбираться средняя точка, то есть индекс 1 массива стены (при 3 элементах массив имеет индексы 0, 1, 2). Но если размер не равен 3 (стена не является конечной точкой коридора), то мы берём случайную точку в промежутке между точкой 1 и длиной стены минус 2. Это нужно, чтобы избежать проходов, создаваемых в углу. То есть, например, на стене с длиной 6 мы исключаем индексы 0 и 5 (первый и последний), и выбираем случайную точку среди точек 1, 2, 3 и 4.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Теперь у нас есть позиция точки на стене, в которой будет создаваться новый элемент. Но мы не можем просто начать генерировать элемент оттуда, потому что так он будет заблокирован уже размещёнными стенами. Также важно заметить, что элемент начинает генерироваться с его левого нижнего угла, а затем инкремент выполняется вправо и вверх, поэтому мы должны задавать начальную позицию в разных местах, в зависимости от направления, в котором смотрит стена. Кроме того, первый столбец x и первая строка y будут стенами, и если начать новый элемент прямо рядом с точкой на стене, то мы можем создать коридор, заканчивающийся в углу комнаты, а не в подходящем месте на стене.

Итак, если стена направлена на север, то нужно, чтобы элемент начинался в одной позиции на север по оси y, но в случайном числе позиций к западу по оси x, в интервале от 1 до ширины комнаты-2. В направлении юга ось x действует так же, но начальная позиция по оси y является позицией точки на стене минус высота комнаты. Западная и восточная стены следуют той же логике, только с перевёрнутыми осями.

Но прежде чем всё это делать, нам нужно сохранить позицию точки стены в переменную Vector2Int, чтобы можно было позже ею манипулировать.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Замечательно. Давайте сделаем это.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Итак, мы сгенерировали элемент с размером и позицией, и следующим этапом будет размещение элемента на карте. Но для начала нам нужно узнать, действительно ли на карте есть пространство для этого элемента в этой позиции. Пока мы просто вызовем функцию CheckIfHasSpace(). Она будет подчёркнута красным, потому что мы пока её не реализовали. Мы сделаем это сразу же после того, как закончим то, что нужно сделать здесь, в функции GenerateFeature(). Поэтому не обращайте внимания на красное подчёркивание, и продолжайте.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

В следующей части создаются стены. Пока мы не будем её трогать, за исключением фрагмента во втором цикле for.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Во время написания этого поста я заметил, что эти конструкции if-else совершенно неверны. Например, некоторые стены в них будут получать длину 1. Так происходит потому, что когда позиция должна прибавляться, допустим, к северной стене, то если она была на углу с восточной стеной, она не добавится к восточной стене, как и должна. Это вызывало раздражающие баги алгоритма генерации. Давайте их устраним.

Исправить их довольно просто. Достаточно удалить все else, чтобы позиция проходила через все конструкции if, а не останавливалась на первой, если та вернула значение true. Затем последнюю else (ту, которая не else if) мы меняем на if, который проверяет, что позиция уже добавлена как Wall, и если это не так, добавляет её как Floor.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Потрясающе, мы почти здесь закончили. Теперь у нас есть совершенно новый элемент, создаваемый на нужном месте, но он такой же, как и имеющаяся у нас первая комната: полностью замкнут стенами. Это означает, что игрок не сможет попасть в это новое место. То есть нам нужно преобразовать точку на стене (которая, как мы помним, хранится в переменной типа Vector2Int) и соответствующую точку на стене нового элемента во Floor. Но только тогда, когда элемент не является первой комнатой.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Этот фрагмент кода проверяет, является ли новый элемент первой комнатой. Если нет, то он преобразует последнюю позицию стены в пол, а затем проверяет направление, в котором смотрит стена, чтобы проверить, какой тайл нового элемента должна превратиться в пол.

Мы достигли последней части функции GenerateFeature(). В ней уже есть строки, добавляющие информацию о создаваемом функцией элементе.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Здесь нам нужно кое-что изменить. Во-первых, тип элемента не всегда равен Room. К счастью, функции передаётся как параметр нужная переменная, а именно строка type. Так что давайте просто заменим здесь «Room» на type.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Хорошо. Теперь, чтобы генерирующий все элементы игры алгоритм работал правильно, нам нужно добавить сюда новые данные. А именно int, который подсчитывает количество созданных элементов и список всех созданных элементов. Поднимемся к месту, где мы объявляем все переменные, и объявим int с именем countFeatures, а также List элементов с именем allFeatures. Список всех элементов должен быть публичным, а счётчик int может быть и приватным.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Теперь вернёмся к функции GenerateFeature() и добавим в конец несколько строк: инкремент переменной countFeatures и добавление нового элемента в список allFeatures.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Итак, наша GenerateFeature() практически завершена. Позже нам нужно будет к ней вернуться, чтобы заполнить пустую функцию CheckIfHasSpace, но сначала надо её создать. Именно этим мы сейчас и займёмся.

Этап 8 — проверяем, есть ли место

Теперь давайте создадим новую функцию сразу после завершения функции GenerateFeature(). Ей нужны два аргумента: позиция, в которой начинается элемент, и позиция, в которой он заканчивается. В качестве них можно использовать две переменные Vector2Int. Функция должна возвращать значение bool, чтобы можно было использовать его в if для проверки наличия места.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Она подчёркнута красным, потому что пока ничего не возвращает. Скоро мы это исправим, а пока не будем обращать внимания. В этой функции мы будем обходить в цикле все позиции между началом и концом элемента, и проверять, равна ли текущая позиция в MapManager.map значению null или там уже что-то есть. Если там что-то есть, то мы прекращаем выполнение функции и возвращаем false. Если нет, то продолжаем. Если функция доходит до конца цикла, не встретив заполненных мест, то возвращаем true.

Кроме того, перед проверкой позицией на null нам нужна строка для проверки, находится ли позиция в пределах карты. Потому что в противном случае мы можем получить ошибку индекса массива и сбой игры.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Отлично. Теперь вернёмся к тому месту, где мы вставляем эту функцию внутрь функции GenerateFeature(). Нам нужно исправить этот вызов, потому что он не передаёт нужных аргументов.

Здесь мы хотим вставить оператор if для проверки наличия достаточного места для элемента. Если результат равен false, то на этом мы завершаем функцию, не вставляя новый элемент в MapManager.map.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Нам нужно передать требуемые аргументы, то есть две переменные Vector2Int. С первой всё просто, это позиция с координатами x и y точки начала элемента.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Со второй всё сложнее, но не намного. Это начальная точка плюс высота для y и ширина для x, с вычитанием из обоих 1 (потому что начало уже учтено).

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Теперь давайте перейдём к следующему этапу — созданию алгоритма для вызова функции GenerateFeature().

Этап 9 — вызов генерируемых элементов

Вернёмся к функции GenerateDungeon(), созданной в предыдущей части статьи. Сейчас она должна выглядеть так:

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Вызов FirstRoom() подчёркнут красным, потому что мы изменили имя этой функции. Поэтому давайте просто вызовем генерацию первой комнаты.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Мы передали необходимые аргументы: «Room» в качестве type, потому что первая комната всегда будет Room, new Wall(), потому что первая комната не создаётся ни из какой другой, поэтому мы просто передаём значение null, и это вполне нормально. Вместо new Wall() можно подставить null, это вопрос личных предпочтений. Последний аргумент определяет, является ли новый элемент первой комнатой, поэтому в нашем случае мы передаём true.

Теперь мы подходим к главному. Используем цикл for, который будет выполняться 500 раз — да, мы попробуем добавить элементы 500 раз. Но если количество созданных элементов (переменная countFeatures) равно максимальному заданному количеству элементов (переменная maxFeatures), то мы прерываем этот цикл.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Первым делом в этом цикле мы объявим элемент, из которого будет создаваться новый элемент. Если у нас создан только один элемент (первая комната), то именно она будет исходной. В противном случае мы случайным образом выбираем один из уже созданных элементов.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Теперь мы выберем, какая стена этого элемента будет использоваться для создания нового элемента.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Учтите, что у нас пока нет этой функции ChoseWall(). Давайте быстренько её напишем. Спустимся вниз, к завершению функции, и создадим её. Она должна возвращать стену, а в качестве аргумента использовать элемент, чтобы функция могла выбрать стену этого элемента.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

В этой функции мы будем находить стену, из которой пока не был создан элемент. Иногда у нас будут получаться элементы, к одной или нескольким стенам которых уже присоединены другие элементы, поэтому нам нужно снова и снова проверять, свободна ли какая-нибудь из случайных стен. Для этого мы используем цикл for, повторяемый десять раз — если после этих десяти раз свободная стена не найдена, то функция возвращает null.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Теперь вернёмся к функции GenerateDungeon() и передадим исходный элемент как параметр функции ChoseWall().

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Строка if (wall == null) continue; означает, что если функция поиска стены вернула false, то исходный элемент не может породить из себя новый элемент, поэтому функция продолжит (continue) цикл, то есть не она не смогла создать новый элемент и переходит к следующей итерации цикла.

Теперь нам нужно выбрать тип для следующего элемента. Если исходный элемент является комнатой, то следующий обязательно должен быть коридором (мы не хотим, чтобы комната прямиком вела в другую комнату без коридора между ними). Но если это коридор, то нам нужно создать вероятность того, что следующим будет ещё один коридор или комната.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Отлично. Теперь нам просто нужно вызвать функцию GenerateFeature(), передав ей в качестве параметров стену и тип.

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

И последнее — перейдите в инспектор Unity, выберите объект GameManager и измените значения на следующие:

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Если теперь нажать на кнопку play, то вы уже увидите результаты!

Как сделать пещеры в юнити. Смотреть фото Как сделать пещеры в юнити. Смотреть картинку Как сделать пещеры в юнити. Картинка про Как сделать пещеры в юнити. Фото Как сделать пещеры в юнити

Как я и говорил, это не самое лучшее подземелье. У нас получилось много тупиков. Но оно вполне функционально, и оно гарантирует, что у вас не будет комнаты, не соединённой ни с какой другой.

Надеюсь, вам понравилось! В следующем посте мы создадим игрока, который будет перемещаться по подземелью, а потом мы превратим карту из ASCII в спрайтовую.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *