Создание генератора карт из 3д тайлов на Unity
Делаю подобие игры Pixel Dungeon, только в 3д варианте. Начал с генератора подземелий. Задумка такая, есть некий набор 3д тайлов, из которых будет собираться случайная карта.
Я уже определил способ соединений этих тайлов между собой.
На тайлах висит скрипт, в котором есть информация о точках стыка, я их именую анкорами. Если есть свободный анкор у первого тайла и есть свободный анкор у второго, то я могу скрепить эти тайлы между собой.
Дальше я приступил к генератору, криво косо я пытался что-то сделать, но чего то путного у меня не вышло. Генератор просто случайно выбирал тайлы и прикреплял их. Разумного поведения я не увидел в генераторе. Точнее создатель не смог его туда вложить. В итоге я понял, что просто рандомно склеивая тайлы меж собой, не выйдет ничего хорошего. Дальше я начал думать, как переделать генератор.
Пока в голову пришли вот такие примерные шаги (ниже рисунок):
- Собрать заранее большие комнаты из тайлов, и случайно расположить их на сцене.
- Пустить лучи из анкоров (из красных квадратиков комнат).
- На некой точке луча (красного), пустить другие перпендикулярные ей лучи (оранжевые лучи), чтобы точно получить пересечения.
- Использовать каким-то образом пересечения лучей для построения коридоров.
Вопросы у меня возникают уже с первого пункта, как правильно устанавливать комнаты, чтобы они не спавнились в миллионах километров друг от друга, как правильно пускать лучи, чтоб они между собой пересекались (Physics.Rayсast() наверно не поможет) и еще куча мелких вопросов, возможно которые я смогу решить. Прошу помочь с основными пунктами.
Возможно я изобретаю велосипед, и уже давно существуют более изящные решения, но я пока не смог найти того, что мне подходит. Укажите мне пожалуйста дорогу. Спасибо.
Ответы (2 шт):
как правильно устанавливать комнаты, чтобы они не спавнились в миллионах километров друг от друга
Думаю здесь нужно забыть что существует 3д и на секунду представить себе 2д карту видом сверху. Можно создать некое "поле" в котором есть сектора - квадратики. В каждый квадратик можно вставить 1-2 твоих примитива карты в случайном порядке (или псевдослучайном). Это решит и проблему милионов километров и ты всегда будешь контролировать какого размера карту нужно генерить. Вполне возможно что у генератора можно ввести дополнительные ограничения - например определенные примитивы карты не должны быть на одной клетке вместе или же повернутыми один на второго твоими анкорами.
Ну или, например, что некие примитивы нельзя ставить если в соседних клетках есть другие примитивы "несовместимые" с этим.
Еще в даном случае можно генерить примитив не в каждой клетке карты, а, например, используя PerlinNoise
как правильно пускать лучи, чтоб они между собой пересекались
для этого в юнити есть RayCast. Для дебага - то ли RayRenderer то ли LineRenderer. Но прийдется расчитывать куда пускать луч.
Если всегда перпендикулярно - нужно сделать твои примитивы так, что бы их анкоры всегда были в одних и тех же точках. То есть 2 разных примитива могут иметь анкор в одной и той же точке "клетки" в которой он будет находится в поле.
Если не всегда перпендикулярно - предлагаю анкоры помечать пустым обьектом с неким тегом, искать их при помощи физикс.сферОверлап по тегу "анкор" и соединять 2 ближайших анкора.
На некой точке луча, пустить другие перпендикулярные ей лучи (оранжевые лучи).
Этой задумки я не понял, так что и прокоментировать никак не могу.
Использовать каким-то образом пересечения лучей для построения коридоров.
Нагуглил вот это:
http://wiki.unity3d.com/index.php/3d_Math_functions
LineLineIntersection() , ClosestPointOnTwoLines()
Вобщем сам с таким дела не имел, но такие вот мысли возникли по ходу прочтения вопроса. Буду рад если помог чем-либо :)
Определенно велосипед. Есть много разных подходов, с разными результатами и для комнат и для пещер. Google: 2D Dungeon Generator
Например подход в котором карта будет в неком прямоугольнике и генерация через его деление в случайных местах:
Более сложный подход через разброс по физике и триангуляции комнат:






