Привет всем. Прежде всего, я приношу извинения за проблемы с этим текстом. Я пользуюсь Яндекс-переводчиком :)
Вы можете прочитать оригинал статьи на английском языке здесь: https://store.steampowered.com/news/app/1646120/view/3183492...
Я подумал, что было бы неплохо написать небольшой пост о механике нашей боевой системы в Citizens: Far Lands. Его разработка заняла некоторое время, и он прошел капитальный ремонт, поэтому я думаю, что уроками, которые я извлек из него, можно было бы поделиться с более широким сообществом для общего блага :)
Для тех из вас, кто не увлекается программированием, я постарался сделать это легко. Возможно, вам все еще будет интересно посмотреть, как все это работает "изнутри".
Изначально боевая система в Citizens начиналась как пошаговая система. С самого начала он был написан так, чтобы его можно было использовать как можно чаще. Хотя я не очень хороший программист, я стараюсь делать свои системы похожими на плагины: что-то, что я могу просто легко добавлять и удалять из программы, над которой я работаю.
Первоначально основными требованиями были:
- Несколько солдат (назовем их подразделениями) должны двигаться вместе, как единое целое. Мы будем называть эти "Флаги".
- Каждый флаг имеет статистику, которая всегда одинакова, а некоторые из них увеличиваются или уменьшаются с каждым подразделением в блоке. Например, урон должен быть увеличен, когда есть больше субъединиц, и должен уменьшаться по мере их смерти.
- У каждого подразделения есть свой собственный аниматор, они должны иметь возможность двигаться, атаковать, умирать и бездействовать
Я начал с разработки базового компонента, называемого "Единичный объект". Это был объект с возможностью написания сценариев, который определял, что такое единица измерения, как она называется, какую статистику она имеет и так далее. Со временем он будет расти, чтобы получить дополнительные параметры, но я начал с некоторых простых, таких как здоровье и урон.
Здесь вы можете увидеть результат и. Вот как мы определяем "Лучника". Есть некоторые дополнительные необязательные параметры, которые оставлены пустыми (например, юниты могут иметь уникальные носители баннеров). Если юнит бросает ракеты, мы тоже можем указать их (стрелы, топоры, гигантские цыплята ...). Важный список, на который следует обратить внимание, - это "Ключевые слова". Позаимствовав идею из настольных стратегических игр (kings of war, warhammer), мы определяем, что такое юнит, задавая ему набор строк. "Ракета", "Пехота", "Кавалерия" и так далее. Таким образом, мы также можем добавить модификаторы "защита" и "атака", которые основаны на указанных ключевых словах. Мы обсудим это позже.
Скриптовые объекты хороши тем, что они предоставляют дизайнеру визуальный интерфейс, позволяющий быстро и легко изменять статистику юнитов. Если бы мы пытались сделать игру модифицируемой (так что, в принципе, если бы мы писали ее снова :) ), я бы, вероятно, сделал что-то вроде этого, но конечный результат был бы преобразован в XML-файл, считываемый из потоковых ресурсов.
Следующая часть - это подразделение. Подразделение - это сборный модуль, который определяет отдельного солдата. У него есть своя сетка, аниматор и компоненты, необходимые для его работы.
Компонент SubUnit содержит в основном данные и несколько вспомогательных методов. Большая его часть заполняется во время выполнения менеджером сражений (родительский флаг, отряд, якорь и так далее). В нем есть несколько основных элементов управления для анимации, таких как "перемещение", "бездействие", "смерть" и "атака". Компонент анимации солдата - это, по сути, оболочка для аниматора. Он обеспечивает немного более дружественный интерфейс.
Чем полезна солдатская анимация:
Последним и наиболее важным компонентом является компонент "Флаг". Компонент Flag содержит все методы и параметры, с которыми постоянно взаимодействует менеджер сражений. Поскольку мы ленивы, мы используем встроенный агент Navmesh от Unity для перемещения войск. Флаг обнаруживает свое собственное движение и сообщает всем своим подразделениям: "Эй, я сейчас двигаюсь, воспроизведите анимацию перемещения". Флаги могут увеличивать и уменьшать количество активных субъединиц, поэтому нам тоже нужны методы для них. Каждая добавляемая нами субъединица увеличивает здоровье и урон, но оставляет некоторые другие статистические данные, такие как скорость передвижения или скорость атаки, неизменными. Всякий раз, когда субъединица умирает, они уменьшаются.
Поскольку мы отошли от пошаговой системы, атака ведется в режиме реального времени. Есть простой таймер, который отсчитывает время, чтобы проверить, достаточно ли времени прошло между атаками, чтобы можно было провести еще одну. Когда таймер истечет, юнит попытается атаковать выбранную цель. В выборе целей есть определенная логика, но для этого потребуется собственный длинный пост.
Итак, атаки! Помните ключевые слова, которые я упоминал? Нанесение урона само по себе довольно просто. По сути, мы просто убираем количество урона от здоровья флага, но есть уменьшение и усиление урона. Отряд копейщиков может получить 50% бонус к атаке против ключевого слова "Кавалерия". Юниты, стоящие в лесу, могут получить 50% бонус к защите от ключевого слова "Ракета". Модификаторы местности также могут внести большой вклад! Мы можем влиять на дальность, скорость юнита, усиление урона, уменьшение урона, скорость атаки... всякие вещи.
В целом, система работает довольно хорошо. Если у вас есть правильные анимации и сетки, дизайнер может настроить новый, полностью функционирующий модуль за несколько минут. Я надеюсь, вам понравился этот маленький дневник разработчика, и, возможно, он натолкнул вас на некоторые идеи, если вы работаете над своим собственным материалом.
Наш следующий дневник разработчиков будет посвящен искусственному интеллекту и самим полям сражений!