История о выборе пути

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

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

История о выборе пути Unity3D, Инди, Gamedev, Elementalsreborn, Длиннопост, Разработка

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


Теперь собственно к проблеме поиска маршрутов между башнями. Первая мысль, которая приходит когда необходимо сделать передвижение отряда из точки А в точку Б без необходимости динамически менять маршрут - это заранее расставить точки на карте и передвигать по ним отряд с необходимой скоростью движения. Второй вариант был использовать одну из бесплатных библиотек динамического поиска пути A* Pathfinding Project.

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


У A* Pathfinding Project есть поддержка Unity3D, так что добавить построение маршрутов в игру заняло не более пары часов. На сцене можно настраивать размер ячеек в сетке проходимости, для моей игры требовалась как минимум 70х50 сетка, средний размер пути был 40-60 точек, а результат был мягко говоря не впечатляющим:

История о выборе пути Unity3D, Инди, Gamedev, Elementalsreborn, Длиннопост, Разработка

Почитав темы с поиском пути в играх пришел к выводу, что нужно использовать сглаживание поворотов, к счастью в этой библиотеке сделать это просто: нужно добавить компонент SimpleSmoothModifier на объект с Seeker (у которого вызывается метод поиска пути). Результаты работы сглаживания меня вполне устраивали.


Без сглаживания и после использования 3 итераций:

История о выборе пути Unity3D, Инди, Gamedev, Elementalsreborn, Длиннопост, Разработка

Появилась новая проблема - даже после увеличения ячеек сетки проходимости, средняя длина сглаженного пути составляла полсотни точек. Поиск и сглаживание всех маршрутов на мобильных устройствах стал занимать безумное количество времени при загрузке уровня (в среднем +5с на планшете Nexus 7) и забивать всю оперативную память на слабом телефоне.

Вообще данная проблема решается просто: необходимо было всего лишь просчитать пути и их длину в редакторе и сохранить в префаб. Наверняка создатели библиотеки предусмотрели такую возможность...

История о выборе пути Unity3D, Инди, Gamedev, Elementalsreborn, Длиннопост, Разработка

Беглый просмотр кода в AstarPath показал, что методы поиска пути могут работать и в editor режиме, необходимо только в нескольких местах убрать строку

if (!Application.isPlaying) return;

которая прерывает выполнение метода если игра не запущена.

Чтоб использовать сглаживание пути, необходимо так же добавить аттрибут [ExecuteInEditMode] к классам Seeker и SimpleSmoothModifier, нам нужно чтоб в этих классах при запуске сцены сработал метод Awake в режиме editor и класс получил все необходимые ссылки на компоненты для работы с модификацией пути. Осталась только одна проблема - сам поиск пути происходит в методе Update, который в редакторе срабатывает при изменении свойств объектов. Можно вызывать этот метод вручную до тех пор, пока все пути не будут просчитаны, или просто потеребить какой-нибудь из объектов на сцене для срабатывания достаточного количества методов Update.


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

1. При нажатии на первую кнопку на сцене создается новый объект, содержащий настройки для создаваемой башни. Во-первых это позволяет визуально отображать всю информацию в режиме редактора, во-вторых при изменении уровня, элемента или типа башни - скрипт автоматически пересоздает отображаемый скин. Это очень экономит время при создании схем уровней.


Слева на картинке компонент с настройками параметров башни из п.1, справа - интерфейс для ручного изменения пути из п.4

История о выборе пути Unity3D, Инди, Gamedev, Elementalsreborn, Длиннопост, Разработка

2. Когда все башни расставлены, время вызвать второй метод редактора. Он создает объекты Path из каждой башни к каждой другой башне, в которых хранится информация о координатах всех точек пути и длина этого пути. На самом деле создается только половина путей (нет смысла отдельно просчитывать путь A -> B и B->A.) На этом этапе каждый путь представляет из себя отрезок из точки А в точку B.


3. При нажатии на третью кнопку метод пробегается по всем созданным объектам Path и вызывает поиск пути между заданными точками. После этого необходимо вызвать пару десятков срабатываний метода Update у класса AstarPath до тех пор, пока все пути не будут просчитаны.


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


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


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

Лига Разработчиков Видеоигр

6.7K поста22.1K подписчиков

Добавить пост

Правила сообщества

ОБЩИЕ ПРАВИЛА:

- Уважайте чужой труд и используйте конструктивную критику

- Не занимайтесь саморекламой, пишите качественные и интересные посты

- Никакой политики


СТОИТ ПУБЛИКОВАТЬ:

- Посты о Вашей игре с историей её разработки и описанием полученного опыта

- Обучающие материалы, туториалы

- Интервью с опытными разработчиками

- Анонсы бесплатных мероприятий для разработчиков и истории их посещения;
- Ваши работы, если Вы художник/композитор и хотите поделиться ими на безвозмездной основе

НЕ СТОИТ ПУБЛИКОВАТЬ:

- Посты, содержащие только вопрос или просьбу помочь
- Посты, содержащие только идею игры

- Посты, единственная цель которых - набор команды для разработки игры

- Посты, не относящиеся к тематике сообщества

Подобные посты по решению администрации могут быть перемещены из сообщества в общую ленту.

ЗАПРЕЩЕНО:

- Публиковать бессодержательные посты с рекламой Вашего проекта (см. следующий пункт), а также все прочие посты, содержащие рекламу/рекламные интеграции

- Выдавать чужой труд за свой

Подобные посты будут перемещены из сообщества в общую ленту, а их авторы по решению администрации могут быть внесены в игнор-лист сообщества.


О РАЗМЕЩЕНИИ ССЫЛОК:

Ссылка на сторонний ресурс, связанный с игрой, допускается только при следующих условиях:

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

- Ссылка должна размещаться непосредственно в начале или конце поста и только один раз

- Cсылка размещается в формате: "Страница игры в Steam: URL"

4
Автор поста оценил этот комментарий

А чем тебе встроенный в юнити navmesh не угодил?

раскрыть ветку
2
Автор поста оценил этот комментарий

@unkxander, графическая часть довольно приятная. Играли в игру "Mushroom Wars"? Геймплейные гифки еще не делали?

раскрыть ветку
Автор поста оценил этот комментарий
Сюжет в игре будет?
Автор поста оценил этот комментарий

Дайте, пожалуйста, ссылку на гитхаб проекта. Очень интересно посмотреть внутренности игры.

DELETED
Автор поста оценил этот комментарий
Комментарий удален. Причина: данный аккаунт был удалён
раскрыть ветку