[Из песочницы] Ещё одна погоня за мечтой. RTS + eyetracker руками студента

Привет.

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

Под катом вы увидите: подробную историю создания RTS своими руками (концепция, код, интерфейс, баланс, карта, модели) и эксперимент по привязыванию к ней айтрекера как средства ввода.

teoxuuhpeij3pcsm0by2x8laevu.png

Ну что ж, начнем.

На дворе 2014 год.

Своим бакалаврским дипломом я разрабатывал игру под кинект про дуэль двух пуджей, где нужно было уклоняться от атак противника и швырять в него свой крюк (GET OVER HERE!!!).

В магистерской работе я решил шануть дальше. На тот момент в лаборатории при кафедре появилась техническая новинка — айтрекер. Выбор сразу пал на него. То, что работа будет игрой, сомнений не было никаких, оставалось выбрать лишь тематику. После недолгих размышлений понял, что хочу отдать почести стратегии, на которой я вырос и которая открыла мне чудесный мир программирования — Warcraft3.

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

Здесь вступил в дело многолетний игровой опыт. Большинство игр стараются очистить экран от элементов управления, отдавая основное пространство контенту. В стратегиях же интерфейс занимает огромное пространство. Чтобы понять, что представляет из себя определенный юнит, его нужно найти на экране, выделить, перевести взгляд на «панель состояния» и там уже найти нужный параметр. Когда же возникает подобная потребность во время сражения больших армий, такая последовательность действий зачастую создает трудности.

e7vttznlf6xdbnx3h6x67escgmc.png

Возник вопрос: раз мы и так находим юнита на поле, то зачем нам потом его выделять, чтобы считать информацию? Почему бы не получить её, просто взглянув на него? После демонстрации вопрос был трансформирован в премудрое название «Функциональные возможности операционной зоны зрения человека в человеко-компьютерном взаимодействии», что, по сути, означало сравнение эффективности мыши и глаз при решении задачи поиска объекта из множества и считывания с него информации.

Summa Technologiae


Тема есть. Концепция есть. Дело было за выбором технологии. После обзора рынка выбор встал между Unity, UnrealSDK, libGDX, среди которых выбрана Unity + C#. Освоив интерфейс, жизненный цикл объектов на сцене и возможности взаимодействия с ними, я приступил к разработке.

vihgkea3hqzeqet8o8laa2as-44.png

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

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

haieqqfozomeixvcvtvbkyoxx-u.png

Система айтрекинга представляет из себя связку двух компьютеров, один из которых выводит предназначенные для пользователя стимулы (назовем его Демонстратор), а второй собирает и анализирует информацию, поступающую с айтрекера (назовем его Регистратор). Из коробки с айтрекером шел софт, позволяющий синхронизировать две машины, откалибровать регистрацию взгляда испытуемого (у всех свои параметры глаз и самого взгляда), а дальше запустить для просмотра ряд статичных стимулов. В моей же задаче регистрация взгляда должна был абыть интегрирована в постороннюю программу.

Для этого мне пришлось изучить протокол взаимодействия Демонстратора и Регистратора. Передача данных велась через локальную сеть при помощи UDP-пакетов с командами, а значит, мне было необходимо написать свой клиент калибровки, эмулирующий работу дефолтного приложения.

Мне потребовалось покопаться пару дней, чтобы написать клиент. Сначала в качестве стороннего приложения. Оно позволяло пройти калибровку, а затем управлять прямоульником на экране с помощью взгляда. Точнее, прямоугольник отрисовывался в точки фиксации взгляда. Казалось бы, не rocket science, но возможность использовать глаз не как средство получения информации, а как инструмент вывода, влияния на внешний мир, восхищает и шокирует.

Когда все было готово, пришла пора ставить эксперимент.

veeee-5rrkmx9htkamasliofvbw.png

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

kit6o7y27lf4niakdrlhxovoito.png

Каждый юнит обладает определенным количеством здоровья. Все юниты имеют максимальное здоровье, кроме одного, имеющего половинный уровень хп. При выделении юнита мы видим вокруг него рамку с индикатором здоровья. У кого здоровье полное — индикатор зеленый и заполнен полностью. У раненого же юнита он рыжий и заполнен наполовину. Цель — найти среди остальных раненый танк и удержать выделенным в течении секунды. Основным замеряемым параметром является время, неоходимое на выполение этого задания. Эксперимент состоял из 5 уровней, отличающихся количеством юнитов на сцене — 5, 10, 15, 20, 25. Гипотеза была в том, что решение этой задачи при помощи айтрекера потребует меньше времени.

Эксперимент был проведен, данные собраны. Настало время обработки статистики. Я воспользовался привычными для себя средствами — PHP и JavaScript, рассчитал критерий Фишера и обнаружил, что разница между использованием курсора и использованием айтрекера статистически значима. В качестве зависимой переменной, понятное дело, использовалась скорость выполнения задания. Дальше я при помощи D3.js визуализировал результат.

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

7wgmbbq6xyyer9fmgs_utcejlya.png

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


Воу! Успех, слава и тд.

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

Учимся ходить


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

hmy9wvmfr7vdndydczd0kk4uwn8.png

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

Эта мысль стала краеугльным камнем, определившим дальнейшее развитие и полный рефактор моего проекта. К этому моменту у меня сущестовал класс WorldObject от которого наследовались Unit и Building, каждый из которых обладал соответствующим функционалом. Юниты могли передвигаться, атаковать, добывать ресурсы, строить здания. Здания же могли стоять и производить юнитов, а двигаться и атаковать — не могли. Появилось желание сделать охранное здание — башню или турель. Турель должна являться по своей сути зданием, но обладать способностью атаки, свойственной юнитам. Это поломало все мои планы. Нужно было как то выносить функционал атаки из класса Unit…

Но на проблему возможно взглянуть шире. Есть ли ещё какие то промежуточные звенья между задниями и юнитами? Бывают ли ещё какие то ситуации использования возможностей одного класса другим?

Для разбора полетов я решил изучить:, а какие ещё несоответствия подобного рода присутствуют в игре взятой за реферес — Warcraft3. И знаете что? Оказалось их там целая плеяда. Есть здания, которые могут атаковать, например Guard Tower или Orc Burrow. Есть такие, которые могут ещё и двигаться, например Ancient of War. Eсть и юниты, которые не могут атаковать, например Wisp или всякие нейтральные овечки да свинюшки снующие по карте (critters). В моей голове пошли размышления о природе отличия зданий от юнитов и я осознал, что таких отличий нет. Это лишь смыслы, навязанные программе игроками для собственного удобства. Есть только юниты и их способности — передвигаться, атаковать, производить юнитов, строить здания, добывать ресурсы и так далее.

ddomnuyvrvknxepyaep5kyei9cc.png

Очевидным решением ситуации стало создание интерфейсов, которые юниты могут реализовывать. Были созданы: MoveAbility, RotateAbility, AttackAbility, DefenceAbility, HpRegenAbility, DefenceAbility, ProduceAbility, BuildAbility, RepairAbility, SellSelfAbility. Юнит по сути остался лишь контейнером с названием, изображением и моделью. Все остальные способности привязываются к нему поверх.

Brave new world


Теперь дело за концепцией.

Напомню, что дело происходило в 2014 году. Тогда был в жанре стратегий некий застой, и это повлияло на выбор жанра самой игры. Также в те годы переживал явный подъем популярности сеттинг стимпанка. Я был большим фанатом миров, одетых в медь и латунь, окутанных паром, несущихся в свое механическое будущее. Но делать игру только с ударом в стимпанк мне казалось скучным и я искал развитие идеи. Хотелось добавить в игру противостояние. И что может быть максимально противопоставленным техногенной индустриальной цивилизации? Конечно же магия и единение с природой! Да, конечно, вы скажете Arcanum, но черт побери, со временем красота такого сеттинга не теряется. Дальше вы увидите, что проект развился не в клон, сляпанный студентом на коленке, а в нечто совершенно иное. Пожалуй, в полную идеологическую противоположность Арканума.

Кто будет населять этот мир? На мой взгляд, современные фэнтезийные игры (а это ведь в конечном итоге фэнтези) сейчас уперлись в кризис архетипов. Явно это происходит из-за всеобщего оказуаливания, все становится более доступным, а для этого более понятным. Но от этого не менее тошно везде видеть обычных скучных «людей», уныло потрясающих мускулами «орков», прокисших от изящества «эльфов» и иных настолько непонятных и отстраненных, что глаз замылился, «протосов».

Мне хотелось максимально отстранится от этого всего, абстрагироваться. А что может быть более абстрактным, чем шар? Я пошел от этой идеальной геометрической формы. Добавил в неё порцию «зерговой» биоморфности (да-да, согрешил против себя). Подумал: почему бы астрактным существам не иметь фозможность формировать свое тело и все покровные ткани?

q5gldx17oddxtndk0i63s07u2cc.png

Так родились орбы.

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

gmho0eck2q7og92b3omtpvyrjl0.png

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

hcrvui_3ebxyzkjhfvp6srbfw2i.png

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

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

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

Между бубном и шестеренкой


А в чем же развитие?

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

idfuy00jyxgzob9wnesu6sk3bko.png

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

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

И вот у нас есть концепция. А значит, пришло время определиться с тем, кто же будет в нашей игре! Какие юниты и здания, как они будут изменяться. После долгих дискуссий, решили остановиться на базовом для стратегий наборе — рабочий (строит здания, добывает ресурсы), легкий юнит (быстрый, слабый), тяжелый юнит (медленный сильный), катапульта (очень медленный, очень тонкий, дальний бой). Из зданий — база (производит рабочих), гнездо (дает прирост к пище), казарма (производит легкого и тяжелого юнита), мастерская (производит катапульты), святилища/фабрики (позволяет совершить прокачку).

Да, я совсем забыл рассказать про игровые ресурсы. Мы решили остановиться на классической паре — кристаллы + лимит пищи, а также дополнительный ресурс для продвижения по древу развития. Кристаллы добываются из разбросанных по карте залежей (привет starcraft), лимит пищи повышается постройкой специальных зданий — гнезд. Дополнительный ресурс зарабатывается при помощи постройки на ядовитых гейзерах зданий одного из двух типов — святилищ или фабрик. Кроме того, в игре присутствует опыт, который дается за уничтожение армий противника и нейтральных существ. Если игрок зарабатывает новый уровень и имеет святилище или фабрику, то он может прокачать один перк на древе развития.

Но вернемся к юнитам и прокачке.

Долго размышляя, мы продумали, как же ветки прокачки будут модифицировать юнитов. Пришли к следующему:
— Стимпанк+Разрушение будет увеличить урон и дальнобойность юнитов.
— Стимпанк+Созидание нарищивает производственные мощи, одевает всех в броню, а также увеличивает прибыльность каждой ходки работника.
— Магия+Разрушение в свою очередь делает юнитов более быстрыми в атаке и снижает их стоимость, превращает катапульты в стенобитные орудия.
— Магия+Созидание увеличивает запас здоровья, а также существенно увеличивает скорость передвижения.

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

Найти точку равновесия


Все это звучит довольно просто, но, когда мы этот нарратив попытались перенести в пространство чисел, точных значений и их приростов, то все оказалось ОЧЕНЬ ЗАПУТАННЫМ. Легко накидать какие то дельты значений для способностей, например, этот юнит получает +20 к урону, а этот +15 к скорости движения. Но потом очень сложно свести этот огромный массив параметров к балансу.

1t54avxmdeoeb9qqg5taulgqriu.png

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

vuykxs5asvfsoc2zhkpdspczxgk.png

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

Стало ясно, что все значения нужно приводить для каждого юнита к одному или нескольким коэффицентам, которые мы бы могли уже сравнивать. Оказалось, что вся школа и весь университет не готовит тебя к подсчету эффективности работы строителя. Не так очевидно, кто будет больше приносить в казну — тот, кто больше загружает в рюкзак или тот, кто быстрее движется.

Через бессонную ночь математических ухищрений были таки выстроены формулы для просчета эффективности разных типов юнитов и зданий, и этот этап более — менее был пройден.

Тут наверное к вам в головы закрался вопрос:, а как же все это безумие преносилось в игру? Отвечу быстро — первое время методом скрупулезного перебивания. Но к моменту, когда каждая ветка получила по 2 этапа развития в каждую сторону и общее число юнитов дошло до 9, то мой внутренний лентяй-программист взбунтовался. Как это — мне, не-твари-дрожащей, приходится делать такую вот унылую бестолковую рутину?!

Тогда я создал веб-приложение для генерации дерева прокачки.

feukpwxfajna1r1ymbpsbj-nvym.png

nyawtn8pr3gnjt5gw3drqdcoefq.png

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

На выход эта система отдавала JSON, который теперь принимала Юнити и конфигурировала игровые объекты (над этой системой импорта тоже пришлось побиться определенное количество времени, ведь с непривычки строить и обходить деревья было не так то и просто).

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

Музыка Айнур


Здесь хотелось бы вставить ремарку. На протяжении всего рассказа я использую разные местоимения — то Я, то МЫ. Дело в том, что начал проект я в одиночку, провел исследование, создал «движок» игры и тд. Но затем своей активностью я заинтересовал своих товарищей и к процессу присоединились на первых порах двое человек — Владимир Ермаков в роле опытного программиста и Павел Шилин в роле художестенно-описательного консультанта. Потом добавились ещё Анна Трофимова и Николай Морозов помогающие с ландшафтом и программированием, соответственно. К созданию баланса приложил руку и пару ночей своего времени мой хороший товарищ Дмитрий Машошин.

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

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

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

Ну, я и попробовал создать что-то похожее, но свое (хех, этими словами можно писать всю разработку в целом).

ggpwnifdbr837gwlyrzebmeodu0.png

Сначала карта была отрисована и спроектирована на бумаге.

Затем обрисована в Photoshop«e в фомрате черно-белой карты высот. Изначально строгая, затем она приобрела плавность сглаженность и шум. Важным моментом здесь было сохранить различие между непроходимыми гранями поверхностей и спусками и подъемами.

После чего данная структура была выдавлена из плоскости уже в Unity. Получился неплохой рельеф, крайне похожий на игровую карту.

Но что то с ним было не так. Он был полностью белый и громко кричал — ДОБАВЬТЕ МНЕ ТЕКСТУР.

Чем я и занялся.

wbrms4mpwdar3kfwvkyquy0mxj4.png

Свои текстуры рисовать времени у меня не было (каюсь, но время сдачи диплома подходило, и нужно было вертеться), поэтому были использованы текстуры WorldOfWarcraft, скачанные из открытых источников.

jgryevk1wjyvcxkj90nkqwhpras.png

yx7gqtwodsoxh1zq6bpfnd8kccy.png

htuwvyavvwdt5f2t8h5unb44qv0.png

Unity обладает потрясающим функционалом текстурирования, который позволяет рисовать поверх формы текстурами, как кистями. Это позволило быстро разметить зоны, а дальше дело было за детализацией и проработкой. Казалось бы, игровое поле — фоновый второстепенный элемент, но именно на него смотрит глаз игрока на протяжение всей игры, так что хотелось сделать карту по-настоящему интересной и живой. Здесь мне бы хотелось выразить благодарность Ане, которая очень помогла мне с процессом текстурирования и сделала из карты настоящую изюминку.

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

Здесь в дело вступил многоопытный Владимир, который разведал тему и понял, что реализовывать самим какой либо из существующих способов решения задачи слишком трудозатратно. Быстро был найден плагин (модуль?) для Unity решающий проблему — A*. Владимир разобрался в интерфейсе и адаптировал его под наши нужды. После этого юниты начали отлично находить путь даже на другой конец карты, когда пред ними были и скалы, и низины, и прочие радости ландшафта.

После создания мира стал актуальным самый трепетный вопрос — почему все наши юниты это чертовы КУБЫ?

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

Здесь хочется обмолвиться, что до сдачи диплома оставалась пара недель. Рассчитав свои временные возможности, я пришел к тому, что на одну модель и её модификации у меня есть около 4х часов. Пришлось работать быстро, потоком и на пределе возможностей.

Придать форму бесформенному


Встречайте орбов!

rntdbpvuyaqanoybt_xsvev_mai.png

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

yphb6xq1wakfk-oqsb0hh_kiqzw.png

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

t76r3uduagvfqhyx0ymfhpqj9m0.png

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

v-gdzbewudngmt4ghvfqyztjm3w.png

Всего для игры было смоделировано 6 объектов (3 юнита и 3 здания) + 4 модификации (2 магические, 2 технические). На легкого юнита и тотемы не хватило времени, увы.

Все модификации были разработаны таким образом, чтобы часть их изменялась при развитии ветки разрушения, а часть — ветки созидания.

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

В Unity это было добавлено следующим образом — юниты обладают базовыми элементами, например телом, плюс каждый тир прокачки (учитывая базовый) имеет ссылку на соответствующие ему элементы графики. При появлении юнита на сцене создается его базовая часть, а затем в стуктуру WorldObject«a из ассетов добавляются все необходимые обвесы.

Окно в мир


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

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

Для решения задачи построения интерфейса первоначально я собрал аналоги, старые и новые — Command&Conquer, Казаки, Warcraft 3, Starcraft 2, Warhammer, Dota, LoL — и начал анализировать составные элементы.

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

3twqyruzp4ouqhen93pyhfylija.png

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

В те древние времена нативные инструрменты Unity для создания HUD«a представляли из себя небольшой набор элементов, которые необходимо создавать и располагать на экране напрямую через код.

После того, как пишешь прекрасный плавный адаптивный фронтенд на html+css это кажется, конечно, абсолютным дичайшим изуверством, но что ж поделать. Пришлось приспосабливаться, высчитывая различные отступы, постоянно учитывая ширину и высоту экрана.

w3buv6miexno0rlgqy-y89cmtvi.png

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

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

Стало понятно, что отрисовывать все — совсем безнадежное занятие при жестком лимите времени, и я начал поиск альтернатив. Нашел прекрасный проект — GameIcons, создающий бесплатные простые иконки для инди-игр. В нем были найдены все необходимые составляющие и интерфейс был собран.

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

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

1tj0fj8uwhidipggmpstrr9fgwi.png

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

В целях экономии места на экране было принято решение делать полосы здоровья всех юнитов определенной длины (чтобы при прокачках и баффах полоса здоровья в 10000 хп не была от края экрана до края).

nzpwfoxxfri2stlohixe5fua5se.png

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

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

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

Ну и, конечно же, опыт и дерево прокачки.

dcjwekhpthdr5f3ewhckhgg0yzo.png

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

omyh8jrcwa2ftcfwzvj6rzqjifc.png

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

Да, довольно топорно выглядит, но это же было всего лишь начало!

И вот для первого запуска все готово! Ура, большой путь позади, впереди бесконечное пространство вариантов развития.

myid-slaueu4aaycuzdmcnzrp-e.png

Осталось добавить лишь стартовый экран — и вперед, разведывать удивительные просторы Эвенедиума. Ах да, я не говорил, что после усиленного брейнсторма мы таки выбрали название?

ЭВЕНЕДИУМ.

Поехали!


И немного скриншотов для тех, кому не хочется смотреть ролик выше.

scyjvtzukdfmclepmzecs4x3434.png

2x148vxeojpnsy3tdmhdhfz4ydi.png

1kp-prg21tb8nlgzy7dcd0ha25m.png

Finita?


Базовая версия игры была готова.

Да, она очень простая, но это только дало нам повод составить отличный пул тасков на дальнейшую разработку — тут вам и новые юниты, и туман войны, и способности с сопутствующим генератором оных, и новые ветки прокачки, и больше вариативности, и кампания, и мультиплеер, и монетизация…

Да, кстати: защитился я на отлично, но это меня не удивляло. Больше меня будоражило будущее игры, за претворение которого в жизнь я тут же принялся.

Клавиатуры кипели, ещё месяц мы что-то активно писали и вдруг, внезапно, я обнаружил, что прошел уже год разработки! Целый год я корпел над созданием этого детища, обрастал соратниками, и вот мы — команда, перед нами продукт и светлое будущее. Мы решили отпраздновать.

Последний коммит начал встречать всех вот таким постом.

j2viwicnwonqmma0vwda2lcse9m.png

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

Для меня это было неожиданностью. Обидной, ударившей довольно сильно.

Длинного вывода не будет, к чему он? Все описано выше.

В целом я горд, что я погнался за своей мечтой создать мир и довел её до такого состояния.

© Habrahabr.ru