Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Регистрируясь, я даю согласие на обработку данных и условия почтовых рассылок.
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Рыбный дождь — это настоящий симулятор рыбной ловли, позволяющий забросить удочку в настоящие водоёмы со всего мира и поймать ту рыбу, которая там водится.

Рыбный дождь

Спорт, Симуляторы, Рыбалка

Играть

Топ прошлой недели

  • cristall75 cristall75 6 постов
  • 1506DyDyKa 1506DyDyKa 2 поста
  • Animalrescueed Animalrescueed 35 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

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

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
0 просмотренных постов скрыто
6
CrionGames
CrionGames
Лига Разработчиков Видеоигр
Серия Space Turret: Defense Point

Space Turret: Defense Point - Часть 6. Локализация⁠⁠

5 лет назад

Всем привет!

Когда мы только начинали проект, у меня уже тогда была хитрая идея для локализации.

Зачем нужны тонны текстов и подсказок, различных шрифтов, поддержка кириллицы, мучение с подборкой размера текстов... Это всё не нужно, если будут иконки! Вот он, секрет успешной локализации, - думал я! Человечество уже опубликовало тысячи мобильных игр, придумало всевозможные иконки под всё что угодно!

Воодушевившись этой идеей, мы начали работу над интерфейсом. Минималистичный дизайн, простые иконки и никакого текста!


Пример интерфейса

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


Интерфейс окна улучшений турели

Все только самое необходимое и нужное, минимум информации. :D

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

На тот момент у меня были общие знания по переводу, я где то видел использование файлов xml. Но идти по общему шаблону мне не хотелось. Я был уверен, что смогу придумать что то еще. Ведь у нас редактор Unity, наверняка в нем есть механизмы хранения данных... Например, ScriptableObject. В голове крутилась идея, что он может отлично подойти, главное - правильно организовать сами данные. Как обычно, я загрузил голову перед сном, а на утро уже родилась идея :)

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


Пример профиля локализации меню

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


Пример идентификаторов текста enum

Пример функции определения текста

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


Пример использования

Какие плюсы использования ScriptableObject?

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

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

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


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


На этом пока всё, о чем будет следующая статья - я еще не придумал, но обязательно что то придумаю :)

Спасибо, что дочитали!


Ниже я оставлю ссылки на примеры скриптов, может кому то понадобятся

Профиль ScriptableObject

Менеджер локализаций

Скрипт для текстов


Предыдущие статьи:

Часть 5. Игровой ИИ и с чего начать

Часть 4. Противники (продолжение)

Часть 3. Противники

Часть 2. Генератор волн противников

Часть 1. История разработки

Показать полностью 7
[моё] Мобильные игры Gamedev Игры на Android Шутер Онлайн-шутер Unity Длиннопост
21
20
Be3pReDeL
Be3pReDeL
Лига Разработчиков Видеоигр

Сказ о разработке амбициозного проекта 16-ти летним парнем (file547)⁠⁠

5 лет назад

Итак, приветствую всех, кто читает этот пост, который для меня является первым на этой площадке. Сегодня я расскажу вам о том, как 16-ти летний парень (Moony Games... то есть я!), увлеченный разработкой игр, решил шагнуть на качественно новый уровень и немного помечтать, заодно поговорим и о том амбициозном проекте, подающем лично для меня большие надежды на успех. Что ж, приступим!

Это случилось, когда я учился в 8-ом классе. Мы с моим горячо любимым приятелем обсуждали за завтраком в школьной столовой проблему озонового слоя Земли, упоминая негативное влияние наработок Илона Маска на него. Недолго подумав, я как сказанул: «Ну, раз этот самый слой защищает от космической радиации, может ли быть такое, что при его разрушении, люди станут превращаться в ужасных мутантов под её влиянием». На такую мысль я получил следующий ответ: «А что, неплохой сюжет для игры типа Fallout!». Так мы и начали разработку проекта The Sun Was Really Bright (TSWRB), назвав себя DExit Games.

Приходя после школы ко мне домой, или, просто гуляя по вечерам, мы думали над сценарием нашей игры. Покупалось много вкусностей, а затем мы садились за компьютер, открывали Google Документы и писали нашу удивительную историю. Наверное, как и любому другому начинающему разработчику, особенно в столь юном возрасте, нам и не приходилось сомневаться в том, что мы пытаемся забраться слишком высоко и просто не вытянем такой проект, но, наверное, тем и хорош такой подход, что ты работаешь над ним невероятно мотивированным, без малейшего подозрения на провал. Сюжет писался, время шло, и мы потихоньку стали переходить к препродакшену. Поскольку мы живем в городе Норильске, с интернетом до недавнего времени были серьезные проблемы. Я приходил к своей бабушке на работу и, используя почти 3/4 трафика, положенного ей для работы на месяц (около гигабайта всего), выкачивал видео-туториалы по Unity с различных YouTube-каналов (в основном с канала «Владимир Свет Игродельский»). Имея навыки в написании музыки (да и начальное музыкальное образование после окончания музыкальной школы по классу трубы), я сделал несколько треков для игры, а наша одноклассница, которую мы подключили к работе над артом игры, нарисовала нам пару концептов мутантов, которые к сегодняшнему дню, к большему сожалению, не сохранились, однако музыка и сценарий имеются:


Музыка и сценарий

Но всё таки почти через год до нас дошло, что это чересчур амбициозно и разработка была прекращена. Возможно, мы когда-нибудь воскресим и выпустим его!

По прошествии нескольких месяцев, я пришел к довольно логичному выводу - надо начать с чего-то попроще, например, мобильных игр. На свет появляется Moony Games, а я становлюсь независимым разработчиком одиночкой (кстати, название Moony придумала моя девушка (уже бывшая :) ) ). Глаз пал на гиперказуальные игры, они просты в разработке, при этом отлично тренируют в понимании геймдизайна, а мобильный сегмент полон доступных издателей и в целом позволяет разобраться в маркетинге своих творений. Сделав небольшой проект, который я так и не довел до ума, но получил достаточный опыт в разработке на движке Unity, я приступил к созданию Helix Tree (Jumping Tree в будущем).

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

И вот, мама дает мне 2000₽, а я, быстро одевшись, вылетаю на улицу в лютый мороз (градусов, эдак, -30° было) и бегу к ближайшему банкомату, чтобы положить эти деньги себе на карту. Я прихожу обратно домой и плачу взнос в размере 25$ за заветный аккаунт в Google Play. Наконец-то моя игра будет в магазине и все мои друзья и знакомые смогут в нее поиграть!

После релиза первой версии игры, я решил её обновить, добавив больше контента. Я добавил третью платформу в ряду, монетки, за которые можно покупать скины для шарика и ускорители с замедлителями, переименовав игру в Jumping Tree, что стала версией 2.0 Helix Tree. Мы с моими друзьями даже сняли небольшую рекламу по такому поводу:

После релиза игры и размещения её на площадке Publisher Wanted, мне стали приходить письма от различных издателей, но ни с одним из них не удалось довести дело до издания игры - я имел слишком низкие показатели Retention для них. Сейчас я работаю с еще одним издателем, который проконсультировал меня насчет изменений, которые стоит внести в игру для улучшения показателей удержания, и скоро мы запустим тесты. Надеюсь, что из этого что-то выйдет!

Следующей главой в жизни Moony Games стала игра Spooky Croocky. Она была придумана мной на уроке истории уже в 9-ом классе и полностью описана на бумаге, вплоть до кадров игрового процесса и дизайна персонажа.

Летом того года (2019) я отдыхал у своего дяди в Москве, и он решил познакомить меня со своим знакомым программистом, который когда-то работал у них в заведении. Я проехал большой путь и наконец оказался у очень симпатичного домика. Позвонил в дверь и вышел тот самый знакомый - Влад. Влад создал компанию Conundrum AI, которая занимается внедрением машинного обучения и ИИ на производства в различных странах. Я узнал ответы на интересующие меня вопросы о программировании, перенял от них опыт в серьезном ПО-бизнесе и реальной работе программистов.

Мой рассказа о том, что я занимаюсь играми настолько вдохновил их, что они решили «проспонсировать» меня и дали мне 100$ на регистрацию аккаунта разработчика Apple. Так на тот момент 15-ти летнему пацану дала денег компания, сотрудничающая с Nvidia.

Следующей точкой моего путешествия был Калининград, в котором я остановился у бабушки, а заодно сходил и на DevGamm Talks.

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

Таким образом я прокачивал свои навыки и в другой интересной мне сфере - съемке и режиссуре.

Теперь мы переходим к следующей и основной главе моего рассказа, к сегодняшнему дню.

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

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


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


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

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

Так же это становится моим первым опытом в более-менее серьезном 3D геймплее.

На моём YouTube канале так же есть геймплейное видео игры:

Вот такая история моего геймдев-пути получается к 16-ти годам. Если вы заинтересовались file547, то приглашаю вас в сообщество ВКонтакте игры:


file547 - Группа ВК


P.S.: Кстати говоря, столкнулся с проблемой в Google Play. Мой аккаунт разработчика заблокирован притом, что продержался на плаву почти год с последнего предупреждения (и то было о блокировке игры в Северной Корее). Если кто-нибудь из вас сталкивался с несправедливым блоком аккаунта и у вас получилось из него выбраться, то расскажите об этом

Показать полностью 18 3
[моё] Игры Мобильные игры Игры на iOS Игры на Android Unity Реальная история из жизни Gamedev Видео Длиннопост
6
7
CrionGames
CrionGames
Лига Разработчиков Видеоигр
Серия Space Turret: Defense Point

Space Turret: Defense Point - Часть 5. Игровой ИИ и с чего начать⁠⁠

5 лет назад

Всем привет!

С чего начинается искусственный интеллект (ИИ)? А начинается он с объекта, которым ИИ будет управлять. В зависимости от того, как Вы спроектируете свой объект, будет зависеть сложность его управления.

Мы с самого начала разделили наши объекты на разрушаемые и неразрушаемые. Для разрушаемых объектов сделали простой скрипт Health, который позволял задавать Жизнь и имел функцию AddDamage(float damage), через которую наносился урон объекту. Если у объекта заканчивалась Жизнь, он деактивировался.


Противники у нас разрушаемые, но кроме параметра Жизнь, им нужны были еще параметры  Скорость передвижения, Скорость поворота, Наносимый урон, Дальность атаки и Точность попадания. И еще Уровень противника, от которого будут зависеть некоторые показатели.

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


Пример настройки фрегата

Для чего нужно наследоваться от класса Health?

В игре есть пули, ракеты и лазеры, которые при попадании наносят урон. Так как у нас только один класс отвечает за разрушаемость, то нам достаточно проверить, есть ли скрипт Health у объекта, куда попала пуля. И если есть - нанести урон.


Сейчас хочу сказать, что общая структура противников получилась очень удобной и понятной. Если нам нужны были какие то дополнительные параметры для корабля, то мы уже создавали новый класс на базе SpaceShip (например, для авианосца нужна ссылка на объект-истребитель, а также два параметра - лимит истребителей и задержка между их запуском). Параметры корабля инициализировались в скрипте Генератора противников, перед выходом корабля из варпа.

Ну что, теперь у нас уже есть некоторые параметры для нашего ИИ.


На чем сделать ИИ?

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

Раз нейронные сети отпадают, то оставался вариант - машина состояний (state machine). Такой вариант хорошо вписывался в общую концепцию поведения кораблей, потому что любое поведение кораблей можно было разделить на составляющие - подлететь к базе, отлететь от базы, приблизиться на определенную дистанцию, лететь к выбранной точке А, повернуться стороной и т.д.


Визуализация двух состояний истребителя

Оставалось выбрать, как реализовать машину состояний:

1. писать свой "движок" для состояний;

2. использовать какой то готовый "движок".


Перед тем, как что то выбрать, сначала надо изучить доступные варианты. В интернете мы нашли много различных готовых "движков", а также подробных инструкций, как сделать свой движок. Но при этом, мы нашли информацию, что в Unity уже есть встроенная машина состояний - это Аниматор. Изначально, задача аниматора в Unity - это проигрывание разных состояний анимации персонажа - бег, ходьба, атака и тд. Но при необходимости, можно добавить выполнение кода в состояние. Вот она, лазейка :)

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

Получается, мы можем писать логику ИИ практически без всякой нагрузки на главный процесс игры! Это же какая оптимизация получается! :) Только при разработке кода, нужно учитывать, что код выполняется параллельно, и если мы будем менять какие то общие переменные, то нужно делать это безопасно, с использованием блокировок.


Состояния аниматора Unity

Чтобы использовать код в состояниях, нужно написать скрипт, который наследуется от класса StateMachineBehaviour. Мы постарались сделать некий удобный шаблон, который использовали во всех подобных скриптах.


public class StateTemplate : StateMachineBehaviour
{
[Header("Parameters")]
//тут можно объявить всякие параметры
[Header("State settings")]
public string onExitDeactivate = "stateA";
public string onFinishActivate = "stateB";  //приватные переменные

public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)

{
//вызывается при каждом входе в состояние
//через animator.GetComponent можно получить доступ к скриптам объекта
}
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
//пока состояние активно, постоянно вызывается
//если нужно выйти из состояния, вызываем animator.SetBool(onFinishActivate, true);
}
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
//вызывается при каждом выходе из состояния
animator.SetBool(onExitDeactivate, false);
}
}
Каждое состояние у нас связано с определенной переменной типа bool в аниматоре.
Когда нам нужно выйти из состояния А, мы активируем переменную stateB, и у нас состояние переходит в состояние B. При этом, переменная stateA сразу деактивируется. Функция OnStateUpdate вызывается либо каждый кадр, либо каждый "физический тик", в зависимости от настроек аниматора.

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

Также важно учесть, что внутри функций нельзя объявлять переменные, иначе при параллельной работе значения будут перезатираться. Все переменные объявляются как атрибуты класса и будут принадлежать одному противнику (владельцу аниматора). Это особенность аниматора Unity.


Разработка ИИ

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

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

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

3. Крейсеры и Авианосцы также имеют два состояния - подлетают к станции и после этого поворачиваются одной из сторон к станции и открывают огонь.


В дальнейшем, мы улучшили поведение истребителей. Потому что изначально, каждый из них летал самостоятельно, кто то нападал, другой в это время отлетал. Получалось какое то месиво. Этот тип кораблей стал самым ненавистным в игре :) Мы хотели их как то сгруппировать, чтобы игроку было удобнее и зрелищнее их уничтожать. И тут мне попадается статья о симуляции полета стаи птиц под названием Boids. Увидев эту симуляцию, мы просто загорелись желанием реализовать подобное поведение у истребителей! Через несколько вечеров доработка была готова!

Теперь каждый истребитель присваивался группе. "Голова" группы выбирал куда лететь - на станцию или от станции, все остальные члены группы следовали за ним с помощью алгоритма Boids.


Состояния ИИ истребителя

Теперь у истребителей было три состояния:

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

2. Fly Back - это состояние для "головы" группы, истребитель выбирает случайное направление и удаляется от станции.

3. Chase - это также состояние для "головы" группы, истребитель приближается к станции.


Демонстрация нового ИИ истребителей

Перейти к видео

Результаты оказались просто потрясающими! Новое поведение истребителей стало гораздо зрелищнее и приятнее :)


Если кому то будет интересно, как именно писать код для состояний, то вот пример скрипта, который случайно поворачивает Крейсер влево или вправо и открывает стрельбу по игроку NetRotateSide.cs


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

В следующей статье я расскажу о том, как мы делали локализацию.

Если у Вас есть идеи поведения противников - делитесь!

Всем хорошего кодинга!


Предыдущие статьи:

Часть 4. Противники (продолжение)

Часть 3. Противники

Часть 2. Генератор волн противников

Часть 1. История разработки


Ссылка игры в Google Play: Space Turret: Defense Point

Показать полностью 3 1
[моё] Мобильные игры Gamedev Игры на Android Шутер Онлайн-шутер Unity Видео Длиннопост
20
7
CrionGames
CrionGames
Лига Разработчиков Видеоигр
Серия Space Turret: Defense Point

Space Turret: Defense Point - Часть 4. Противники (продолжение)⁠⁠

5 лет назад

Всем привет!

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


Крейсер Паршивых Пиратов

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

Перейти к видео

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


Авианосец Кровавых Пиратов

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

Перейти к видео

Этот корабль дополнительно оборудован ракетными установками. Пока истребители будут отвлекать противника, Авианосец сможет нанести критические повреждения станции. Современные маневровые двигатели обеспечивают отличное уклонение от снарядов противника.


Линкор Наемников

Наемники обладают самыми совершенными военными технологиями в области кораблестроения.

Перейти к видео

Именно они смогли построить первый Линкор, благодаря которому добились своей жестокой известности. На текущий момент это самый большой, мощный и хорошо вооруженный корабль. На своем борту он имеет целых 10 тяжелых ионных орудий, вмонтированных в корпус корабля. Также имеется ангар для истребителей, вместимостью до 50 кораблей! Еще ни одна станция не смогла отразить нападение Линкора!


Дредноут Враждебной Империи

Пираты, Наемники... Их мощь и сила никогда не сравнятся с силой Империи! Обладая всеми ресурсами галактики, они смогли построить Дредноут!

Перейти к видео

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


Флагман Зоргов

Вселенная таит в себе много опасностей, но появление Флагмана Зоргов - было абсолютной неожиданностью.

Перейти к видео

Именно этот противник является "мозгом" всей расы Зоргов. Способен выпускать огромный луч разрушающей энергии, расщепляющий всё на своем пути. Имеет на борту множество различных защитных систем. Одна из них - особый щит, который защищает Флагман от любых повреждений. Щит поддерживается специальными Дронами-Защитниками. Это Абсолютное оружие, настоящий Армагеддон всего живого!


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

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

Если у Вас есть вопросы или замечания - пишите, с радостью отвечу :)


Предыдущие статьи:

Часть 3. Противники

Часть 2. Генератор волн противников

Часть 1. История разработки


Ссылка игры в Google Play: Space Turret: Defense Point

Показать полностью 4
[моё] Мобильные игры Gamedev Игры на Android Шутер Онлайн-шутер Unity Видео Длиннопост
0
26
gremlinbl
gremlinbl
Лига Разработчиков Видеоигр

Ненависть к Low Poly графике⁠⁠

5 лет назад

Написав очень спорный пост 5 советов как в одиночку доделать свою 3D игру. Я понял, что не все поняли мой посыл. Он был не о том, что надо делать игры с откровенно слабой графикой и прочим непроработанным окружением (звуками и иконками). А о том как обычному человеку, который всю жизнь мечтал создать свою игру, оптимизировать свою работу и довести работу до конца. О том как ставить реальные цели и планы и не разочароваться в своём проекте и не забросить его, а вместе с ним и своё любимое хобби - индигеймдев.

По моему мнению, самым спорным моментом был выбор графики в стиле Low Poly. Когда я общался с людьми, которые еще не видели мой проект, но уже знали, что он в Low Poly, часто видел прямо ненависть по отношению к этому стилю. Иногда это было прямым текстом. Но поиграв в мою игру, они меняли своё мнение и выражали удивление тому, что Low Poly может иметь такой приятный вид даже в сеттинге Dark Fantasy.

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

Почему важно на начальном этапе проекта, особенно инди-одиночки не делать очень проработанную графику? Ответ прост, проработанная графика - это очень долго. Я на свою игру потратил 2 года и это с учётом, что она в Low Poly. Из-за отсутствия опыта новички не могут объективно оценить трудозатраты на реализацию графики (да и других аспектов). Если игра состоит более чем из одного персонажа, то нарисовав одного, человек может понять на сколько много осталось сделать и бросить эту затею. Графику вы сможете доработать (если очень захочется) в дальнейшем уже на последних этапах или вообще в каких-нибудь обновлениях и новых версиях игры.

Данный стиль - это компромис, идите от простого к сложному. Честно сказать, я не сам дошёл до мысли, что этот стиль такой полезный. На просторах Ютуба, случайно натолкнулся на англоязычную лекцию о том как Low Poly экономит деньги разработчикам игр (https://www.youtube.com/watch?v=H1oNuKChsdU&t=836s). А мы ведь с вами скорее всего не имеем огромных бюджетов, да и вообще это хобби.

А так, конечно не претендую на истину в последней инстанции.

Чтобы не быть голословным, вот ссылка на мою пошаговую стратегию под Android https://play.google.com/store/apps/details?id=com.lightGamed...

Сообщество проекта в VK: https://vk.com/warriorsofmedievalwalls

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

Показать полностью 6
[моё] Игроделы Игры на Android Инди Gamedev Unity IT Стратегия Моя игра Длиннопост
30
16
CrionGames
CrionGames
Лига Разработчиков Видеоигр
Серия Space Turret: Defense Point

Space Turret: Defense Point - Часть 3. Противники⁠⁠

5 лет назад

Всем привет!

Сегодня я расскажу и покажу то, что большинство игроков не сможет увидеть в игре. Мы очень долго старались это скрывать, практически целый год (10 месяцев). Это те вещи, над которыми мы работали ночами, куда вкладывали максимум усилий. Более того, мне пришлось вложить часть своей души в одну из вещей, чтобы сделать ее ошеломительной.

Итак, речь пойдет о противниках и я их покажу крупным планом!


Истребители

Самый первый противник, которого встречает игрок - это истребитель.

Перейти к видео

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


Фрегаты

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

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


Крейсеры

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

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


Взрыватели

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

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


Авианосцы

Только однажды одному из шпионов ценой собственной жизни удалось получить секретную информацию о разработке пиратов - Авианосцах.

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


Зорги

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


Дроны-Разведчики

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


Дроны поддержки

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

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


Штурмовые дроны

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


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


Предыдущие статьи:

Часть 2

Часть 1


Ссылка игры в Google Play: Space Turret: Defense Point

Показать полностью 8 1
[моё] Мобильные игры Gamedev Игры на Android Шутер Онлайн-шутер Unity Видео Длиннопост
16
19
CrionGames
CrionGames
Лига Разработчиков Видеоигр
Серия Space Turret: Defense Point

Space Turret: Defense Point - Часть 2. Генератор волн противников⁠⁠

5 лет назад

Всем привет!

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

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

Но сегодня я попробую подробно описать один из вариантов генерации противников.

Для начала, надо понимать, что нам нужно от генератора:

1. Игроку требуется пройти раунд;

2. Каждый раунд состоит из набора волн;

3. Каждая волна состоит из противников одного типа;

4. Генератор волн должен генерировать новую волну при определенных условиях;

5. Расположение противников генерируется случайно в некоторой области игрового пространства.


Распутывать этот клубок лучше всего с конца.


Расположение противников

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

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


Пример генерации малого куба

Как можно расположить противников внутри малого куба? Тут может быть множество вариантов, но лучше всего начать с простых:

1. Задать случайные позиции;

2. Задать одинаковые позиции (все противники появляются из одной точки);

3. Задать позиции по горизонтали слева направо (или справа налево);

4. Задать позиции по вертикали сверху вниз (или снизу вверх).


Схематичные примеры расположения, вид спереди

При этом, в вариантах 3 и 4 можно дополнительно отражать расположение по горизонтали или вертикали относительно центра малого куба. Схематично это выглядит так:

Между генерацией противников можно указать задержку. Это положительно скажется на производительности, т.к. одновременное создание множества объектов требует значительного времени и пользователь может заметить такие лаги. Зная количество противников, можно рассчитать расстояние между точками (Количество противников будет случайным в диапазоне, но об этом чуть ниже).

Итого, из примитивных вариантов генераций у нас уже получается хороший набор :)

В игре такие способы расположения выглядят весьма неплохо!


Пример горизонтального отражения

Пример горизонтального и одновременно вертикального отражения

Когда генерировать новую волну?

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

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

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

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


Указание типа противника

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


Если постараться это всё обобщить, то получится следующая структура для волны противников:

Данные генерации
-генерация волны: последовательная или параллельная;
-начальная задержка перед генерацией волны.
Данные расположения
-тип расположения противников: один из шести видов;
-задержка между генерацией;
-размер малого куба (относительно большого);
-позиция малого куба (относительно большого);
-горизонтальное отражение: да\нет;
-вертикальное отражение: да\нет.
Данные противника
-ссылка на объект (префаб);
-уровень противника;
-минимальное и максимальное количество.

Настройка раунда

Для хранения списка волн мы решили использовать специальный объект в Unity - ScriptableObject. Данный объект представляет собой что то типа профиля настроек.


Пример заполнения настройки раунда

Тестирование

После создания десяти раундов с постепенным увеличением сложности, мы успешно протестировали их. И после этого сделали сборку игры для тестировщиков :) Почти все тестировщики попросили сделать раунды более сложными, т.к. в текущих раундах было очень мало волн (5-10) и они быстро кончались.

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

Пришлось думать, как можно это упростить.


Упрощение

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

Но вскоре и эта проблема была решена. Я придумал использовать игровые очки!

Когда система генерирует противника, противник будет использовать некоторое количество очков. Различные типы противников будут использовать различное количество очков, например:

Истребитель - 1 очко;

Фрегат - 2 очка;

Крейсер - 4 очка и т.д.

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

Например, 1 раунд - 30 очков, 2 раунд - 35 очков и т.д.

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

Так как раунд состоит из волн, то  каждая волна также будет "запрашивать" некоторое случайное количество очков и на полученные очки генерировать противников. К примеру, от 5 до 10 очков на волну. Если у волны будет 10 очков, то на них можно создать 10 истребителей или 5 фрегатов. Чтобы в первом раунде не появились сразу мощные противники - крейсеры, то можно указать номер раунда, после которого волна будет доступна для генерации. Также, с каждым новым раундом, очки для волн будут увеличиваться.


Теперь, если всё обобщить, то для настройки одной кампании потребуется:

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

Пример заполнения профиля кампании

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

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

Пример заполнения профиля типа противника

После того, как мы внедрили новую систему генерации, настраивать уровни стало гораздо проще и быстрее! Но оставалась одна проблема: т.к. мы использовали случайные числа, то у нас каждый раз генерировались разные последовательности противников при повторном прохождении раунда. Чтобы решить эту проблему, нам нужна была последовательность случайных чисел, которую всегда можно было бы повторить. Тут нам очень помог системный генератор случайных чисел System.Random. Этот генератор чисел будет каждый раз повторять псевдослучайную последовательность чисел, если каждый раз задавать ему одно и то же начальное значение. После внедрения System.Random, наш генератор волн стал выглядеть идеально! :)

А самое главное - мы смогли получить позитивные отзывы от тестировщиков!


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

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


P.S.

Я намеренно не выкладываю примеры кода, чтобы не усложнять повествование. Очень надеюсь, что понимая структуру данных для генератора, многие смогут самостоятельно написать код для его работы :) Но если возникнут затруднения или будут какие то вопросы - конечно, пишите :)


Ссылка игры в Google Play: Space Turret: Defense Point

Показать полностью 8
[моё] Мобильные игры Gamedev Игры на Android Шутер Онлайн-шутер Длиннопост
4
37
CrionGames
CrionGames
Лига Разработчиков Видеоигр
Серия Space Turret: Defense Point

Space Turret: Defense Point - История разработки, часть 1⁠⁠

5 лет назад

Всем привет!

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

Игру пишу с другом из Германии, оба очень любим разрабатывать игры. Работаем айтишниками, в свободные вечера работаем над игрой на платформе Unity.

Зарождение

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

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

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


Геймплей, который мы себе представляли на тот момент

Перейти к видео

От идеи к реализации

После обсуждения базовых механик приступили к реализации.

Достаточно долго думали над управлением камерой. В итоге сделали два варианта:

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

Пример такой работы как раз на видео ниже, с кубиком.

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


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

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

Перейти к видео

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

В итоге наткнулись на такой ролик с обалденным эффектом варпа! (качество не айс, зато оригинал)

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

В итоге, получилось воспроизвести похожий эффект!

Перейти к видео

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


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


Пример тестирования производительности графики и наведения турели на цель.

60 ФПС очень воодушевляло, был некий "запас" прочности для дальнейшей разработки. Правда, нас немного смутило, что "крестики", куда прицеливается турель, немного смещены от направления самих кораблей.

Курсоры и наведение на цель

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

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

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


Пример со смещенной точкой наведения

Пример желаемого расположения точки наведения

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

Дело в том, что из-за особенностей алгоритма и точности типа float, точка пересечения корабля с пулей немного смещалась относительно направления корабля.


Схематическое изображение смещения прицела

При этом, если смотреть на цель как бы из ствола турели - то всё было хорошо.

Но вид то у нас от третьего лица! И если смотреть из другой точки, то это смещение становилось сразу заметным.

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

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

Да, на этот расчет тратятся ресурсы процессора, но когда на экране рассчитывается 50 точек пересечения, +- несколько дополнительных точек погоды не сделают :)


На этом первая часть статьи заканчивается, спасибо, что дочитали до конца!


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


P.S.

Если у Вас есть какие-либо вопросы, пишите, с радостью отвечу :)

Первый релиз игры состоялся в начале декабря 2019 года. На разработку первой версии ушло 4 месяца.

Ссылка игры в Google Play: Space Turret: Defense Point

Показать полностью 5 4
[моё] Мобильные игры Gamedev Игры на Android Шутер Онлайн-шутер Видео Длиннопост
4
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии