Найти тему
Petr Nagel Games

Будни GameDev. Создание мини-карты для RTS игры

Сегодня я сделал для игры мини-карту. Рассказываю, что да как.

Так как вся работа идёт на движке Godot, у меня было много вариантов для реализации мини-карты. Это и дополнительная камера, смотрящая на карту сверху, и разного плана проекции, но, так или иначе, все они затрагивают камеру и влияют на производительность лишними рендерами.

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

Шаг 1. Рендер каждой 3D карты отдельно

-2

Так как все сцены у меня в 3D, модели есть в блендере, откуда их можно легко достать в виде 2D картинки. Для обработки использую GIMP, так что на каждую сцену на скриншот + обработка уходило где-то по 4 минуты

Игра немного пикселизованная, поэтому после скриншота качество ещё немного убавил.
В результате на каждую сцену получлся 2D аналог.

-3

Шаг 2. Соотношение 3D карты и 2D карты

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

И решение пришло.

-4

Тут всё, на самом деле, до банального, просто. Черная область на карте - это прямоугольник, обозначающий рамку относительно 3D карды для позиционирования в 2D.

Более наглядно.

-5

Я думаю, вы уже понимаете, как дальше быстро и легко спозиционировать все карты. Просто располагаю черную область так, чтобы карта внутри неё соответствовала расположению карты на 2D скриншоте.

Шаг 3. Координаты и... координаты

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

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

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

Формула расчета координат несложная, но с некоторыми нюансами.

Первый из нюансов, начало координат в 2D сцене - 0,0 по осям X,Y, начало в 3D сцене всегда разное, то есть та черная область может иметь любые координаты по осям X,Z, и они никак не фиксированы. Этот фактор является смещением начальных координат.

Соответственно, чтобы учитывать позицию объекта в 3D сцене нужно от неё отнимать точку начала координат.

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

В псевдо-кодах это выглядит так:

функция проекция3Dв2D(позиция3D) {
позиция3D -= началоКоординат3D // тут сразу и X и Y
позиция2D.X = позиция3D.X / (область3D.ШИРИНА / область2D.ШИРИНА) - смещение
позиция2D.Y = позиция3D.Y / (область3D.ВЫСОТА / область2D.ВЫСОТА) - смещение
вернуть позиция2D
}

В результате функция нам возвращает правильные координаты на 2D карте любого 3D объекта.

Шаг 4. Корректировки

Если вы заметили, в формуле участвует параметр "смещение".

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

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

Итог

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

Всем большое спасибо за внимание!

Так же, мои статьи выходят и на DTF