Как создать свою игру на телефоне? Как сделать свою игру на Андроиде?

❗️ Всем привет, в этом видео я расскажу вам и покажу как создать свою игру на телефоне, если вы не знали как сделать игру на андроиде, то досмотрите это видео до конца. ❓ Мне часто задают вопрос, а именно, как создать свою игру на телефоне андроид? В данном ролике я полностью раскрываю тему о том как сделать игру на телефоне в 2023 году. ❓ А ты знал как сделать игру на телефоне? сделать это с телефона легко и просто. ✔️ Посмотрев это видео «как создать свою игру на андроиде» до конца, у вас больше не останется вопросов и вы сможете понять как создать игру на телефоне в 2023 году. Видео «как сделать свою игру на телефоне андроид» — это полный гайд по этой теме. Узнай как создать игру на андроиде здесь и сейчас. Если я вам помог решить проблему как сделать свою игру на телефоне, то подписывайтесь на канал и ставьте лайк. ❤️❤️❤️ ———————————————————————————————————————————————————— 00:00 — Вступление 00:32 — Как создать свою игру на телефоне? 21:42 — Заключение ———————————————————————————————————————————————————— Мой Телеграм: https://t.me/activpolz
Показать больше
Войдите , чтобы оставлять комментарии
Мобильная 3D игра на Unity3D менее чем за 90 часов

Приветствую! Сегодня я расскажу вам о своем опыте разработки игры на Unity для платформы Android, менее чем за 90 часов, на примере создания простенького «раннера». В процессе повествования я затрону некоторые детали и ключевые этапы, с описанием всех возможных подводных камней и методов их решения. Данная история описывает процесс создания игры для мобильных платформ, начиная от концепции и заканчивая готовым продуктом. Надеюсь, она вдохновит вас на создание собственного проекта, либо поможет пролить свет на некоторые особенности движка Unity. Без лишних слов, приступим к делу!
Этап-1: концепция
Как правило, начинающие разработчики, наступают на свои первые и самые значимые грабли уже на данном этапе, потому что перед тем, как приступить к созданию чего-либо, неплохо было бы оценить собственные возможности. Просто задайте себе вопрос: хватит ли у вас сил, времени и умений на создание проекта ААА класса? Ответ – нет! Отбросьте эту идею в долгий ящик, и не возвращайтесь к ней до тех пор, пока не реализуете чертову дюжину удачных проектов. К слову, под удачей мы подразумеваем количество установок от 500 тысяч, рейтинг свыше 3,5 по 5-ти бальной шкале и коммерческий успех. Для начала, займитесь более простыми, я бы даже сказал приземленными проектами, вроде аркад в стиле addictive games, сочетающих в себе все необходимые нами критерии «удачного» проекта.
Преимущества стиля addictive games:
- Затягивающий, «залипающий» геймплей;
- Отсутствие сюжета;
- Простое и интуитивно понятное управление, требующее от игрока минимум действий;
- Минимальные требования к графике.
Этап-2: создание наброска
Вот мы и подошли к самому главному этапу разработки, и пока с вашего лица еще не сошла разочаровывающая улыбка, позвольте вам напомнить, что набросок – это видение продукта. Создав его, вы фактический утверждаете техническое задание будущей игры, благодаря которому все дальнейшие шаманства и танцы будут исходить именно из этого задания. Степень проработки эскиза определять вам и только вам. В конце концов, этот эскиз вы создаете для себя, а не для галереи искусств. На данном этапе, я просто беру ручку и блокнот, после чего начинаю рисовать, изредка оставляя краткие комментарии и пояснения:

Из наброска видно, что игра предназначена для мобильных платформ, и запускается она будет в портретном режиме. Геймплей также бесхитростен: задача игрока заключается в преодолении опасного машрута на предоставленном игрой автомобиле, попутно собирая кристаллы. За каждый собранный кристалл и удачно пройденный поворот, игрок получает вознаграждение в виде очков бонуса. Касание по экрану заставляет изменять направление движения автомобиля по осям X и Z.
Этап-3: создание прототипа
Имея под рукой подробный план действий, можно смело приступать к созданию «мокапа» или прототипа будущей игры. По сути, данный этап – начало работы с Unity, и начинать его следует с настройки окружения. Вот, как это настроено у меня:

В левой части экрана расположились редактор Scene и Game. Последний отображает то, как именно игра выглядит на устройствах. В правой части: панели Hierarchy и Inspector, а чуть ниже расположены панели Project и Console.
Этап-3.1: под капотом
Внимание! Ниже будет описан простейший код реализации игры, рассчитанный на новичков, и демонстрирующий то, насколько быстро и просто можно добиться результата в Unity. Финальный код игры реализован на более глубоких познаниях языка, включающий проблемы хранения данных, оптимизации и монетизации проекта, однако, по понятным причинам, в данной статье о них говориться не будет. Все скрипты мы будем писать на C#, а тем, кому это не интересно, предлагаю смело переходить к Этапу-4: визуальный дизайн
Мое прототипирование всегда начинается с болванок, то есть в качестве актеров я всегда использую примитивные элементы, вроде кубов и сфер. Такой подход заметно упрощает процесс разработки, позволяя абстрагироваться от всего, что не связано с механикой игры. На первом шаге мы формируем базовое понимание облика будущей игры, а так как по задумке наша игра создается в изометрическом стиле, первое что нам необходимо проделать, это настроить камеру. Тут мы подходим к одной из ключевой особенности Unity. Дело в том, что можно долго экспериментировать с параметрами настройки камеры, подбирая нужные значения… Но проще просто выставить понравившийся ракурс с помощью панели View, а затем активировать GameObject -> Align With View, после чего ваша камера тотчас же примет необходимые значения. Вот такой вот shortcut от создателей Unity.

Итак, сцена готова, но как придать персонажу движение? Для начала, произведем некоторые манипуляции с объектом Sphere, добавив в него такие компоненты как Rigidbody и только что созданный скрипт sphereBehavior. Не забудьте отключить галочку Use Gravity, так как на данном этапе он нам не понадобится.

Если вкратце, то компонент Rigidbody позволяет объекту ощутить на себе все прелести физического мира, таких как масса, гравитация, сила тяжести, ускорение и.т.д. Вот почему для нас он так важен! А теперь, чтобы заставить тело двигаться в нужном нам направлении, нам всего лишь нужно слегка изменить параметр velocity, но делать это мы будем при помощи кода. Давайте заставим сферу двигаться по оси Х, для этого внесём изменения в скрипт sphereBehavior:
using UnityEngine; using System.Collections; public class sphereBehavior : MonoBehaviour < private Rigidbody rb; // Объявление новой переменной Rigidbody private float speed = 5f; // Скорость движения объекта void Start() < rb = GetComponent(); // Получение доступа к Rigidbody > void Update() < rb.velocity = new Vector3 (speed, 0f,0f); >>
В Unity, тела описывают своё положение и направление, посредством специальных векторов, хранящих значения по осям x, y и z. Изменяя эти значения, мы добиваемся необходимого нам направления или положения конкретного тела. Строка rb.velocity = new Vector3(speed, 0f,0f) задает новое направление телу по оси X, тем самым придавая нашей сфере нужное нам направление.
Если вы сделали всё в точности, как и я, то ваша сфера отправится в бесконечное путешествие по оси X, со скоростью speed.
Теперь давайте заставим нашу сферу изменять свое направление, при каждом клике левой клавиши мыши так, как это реализовано в игре ZIGZAG. Для этого мы вновь вернемся к коду sphereBehavior и изменим его следующим образом:
using UnityEngine; using System.Collections; public class sphereBehavior : MonoBehaviour < private Rigidbody rb; // Объявление новой переменной Rigidbody private bool isMovingRight = true; // переменная, отражающая условное направление объекта private float speed = 5f; // Скорость движения объекта void Start() < rb = GetComponent(); // Получение доступа к Rigidbody > void changeDirection() < if (isMovingRight) < isMovingRight = false; >else < isMovingRight = true; >> void Update() < if(Input.GetMouseButtonDown(0)) < changeDirection(); >if (isMovingRight) < rb.velocity = new Vector3 (speed, 0f, 0f); >else < rb.velocity = new Vector3 (0f, 0f, speed); >> >
Условимся, что когда сфера движется по оси X, то это движение называется движением «вправо», а по оси Z – «влево». Таким образом мы легко можем описать направление нашего тела специальной булевой переменной isMovingRight.
if(Input.GetMouseButtonDown(0))
Этот кусочек кода отслеживает нажатие левой клавиши мыши, и если данная клавиша все же была нажата, запускает функцию changeDirection(), с простой логикой: если на момент нажатия левой клавиши мыши, переменная isMovingRight имела значение true, то теперь она стала false и наоборот. Напомню, что булевая переменная позволяет нам ответить на один простой вопрос: истинно ли утверждение о том, что тело движется по оси X, или нет? Иными словами, нажатие на левую клавишу мыши постоянно изменяет значение isMovingRight, то на true(тело движется вправо), то на false(тело движется влево).
Альтернативно, функцию changeDirection() можно записать в одну строку:
void changeDirection()
И последнее, что необходимо сделать, это переписать метод направления движения с учетом переменной isMovingRight:
if (isMovingRight) < rb.velocity = new Vector3 (speed, 0f, 0f); >else
Если isMovingRight имеет значение true (если сфера действительно движется вправо), тогда значение velocity принимает новый вектор направления rb.velocity = new Vector3 (speed, 0f, 0f); Если isMovingRight имеет значение false, значит тело более не движется вправо, а значит пришло время изменить вектор направления на rb.velocity = new Vector3 (0f, 0f, speed);
Запустите игру, проделайте несколько кликов мыши, и если вы сделали все в точности, как и я, то увидите, как сфера начнет описывать зигзаги.
Круто? Конечно нет! Ведь сфера движется, а мы стоим на месте. Давайте доработаем игру так, чтобы мы могли двигаться вместе со сферой и не упускали её из виду. Для этого нам нужно создать скрипт cameraFollow и прикрепить его к объекту Main Camera:

А вот код скрипта cameraFollow:
using UnityEngine; using System.Collections; public class cameraFollow : MonoBehaviour < public GameObject player; public Vector3 offset; void Start () < offset = transform.position - player.transform.position; >void Update () < transform.position = player.transform.position + offset; >>
Как же осуществить слежение за объектом? Для начала нам нужно рассчитать разницу смещения между объектами Camera и Sphere. Для этого достаточно вычесть от позиции камеры, координаты сферы, а полученную разницу сохранить в переменной offset. Но прежде, необходимо получить доступ к координатам сферы. Для этого нам необходима переменная player, представляющая собой простой GameObject. Так как наша сфера находится в постоянном движении, мы должны синхронизировать координаты камеры с координатами сферы, приплюсовав полученное ранее смещение. Осталось только указать в поле player наш объект слежения, и можно смело любоваться результатом. Просто перетащите объект Sphere в поле Player, скрипта cameraFollow, как это показано на картинке (Main Camera при этом должна оставаться выделенной):

Теперь же, давайте подумаем над генерацией дороги, по которой могла бы двигаться наша сфера, ведь сейчас она в буквальном смысле парит в воздухе. Начнем с настройки объекта Cube, представляющий, по нашему мнению, участок пути.
Если в вашем списке нет тэга Ground, то его необходимо создать во вкладке Add Tag.
Следующее, что нам предстоит совершить, это создать в корне проекта специальную папку с названием Prefabs, и перетащить в нее наш Cube, прямо из инспектора. Если после этого, имя объекта Cube стало синего цвета, значит вы все сделали правильно.

Префабы – это особый тип объектов, позволяющий хранить GameObject, а также все его значения и свойства в одном месте. Префабы позволяют создавать бесконечное множество объекта, а любое его изменение немедленно отражаются на всех его копиях. Иными словами, теперь мы можем вызывать участок пути Cube, прямо из папки Prefabs, столько раз, сколько необходимо.
Теперь давайте создадим пустой GameObject, (щелчок правой кнопки мыши по Hierarchy) переименуем его в RoadContainer и прикрепим к нему только что созданный скрипт roadBehavior:


А вот и сам код roadBehavior:
using UnityEngine; using System.Collections; public class roadBehavior : MonoBehaviour < public GameObject road; // Префаб участка пути private Vector3 lastpos = new Vector3 (0f,0f,0f); // Координаты установленного префаба void Start() < for(int i=0; i> >
Что же тут на самом деле происходит? Как видите, у нас есть переменная, которая позже, вручную будет привязана к нашему префабу Cube, и есть объект Vector3, хранящий координаты последнего установленного префаба (сейчас значения равны нулю).
for(int i=0; i


Ок, но что делать дальше? А дальше нам нужно продолжить установку блоков в произвольном порядке. Для этого нам понадобится генератор псевдослучайных чисел random. Подправим скрипт roadBehavior с учетом нововведений:
using UnityEngine; using System.Collections; public class roadBehavior : MonoBehaviour < public GameObject road; // Префаб участка пути private Vector3 lastpos = new Vector3 (0f,0f,0f); // Координаты установленного префаба void Start() < for(int i=0; iInvokeRepeating ("SpawnPlatform", 1f, 0.2f); > void SpawnPlatform() < int random = Random.Range (0, 2); if (random == 0) < // Установить префаб по оси X GameObject _platform = Instantiate (road) as GameObject; _platform.transform.position = lastpos + new Vector3 (1f,0f,0f); lastpos = _platform.transform.position; >else < // Установить префаб по оси Z GameObject _platform = Instantiate (road) as GameObject; _platform.transform.position = lastpos + new Vector3 (0f,0f,1f); lastpos = _platform.transform.position; >> >
Строчка InvokeRepeating («SpawnPlatform», 1f, 0.2f) предназначена для активации функции SpawnPlatform() спустя 1 секунду после начала игры, и повторного её вызова каждые 0.2 секунды. Что касается самой функции, то тут, как говорится все проще пареной репы! Каждые 0.2 секунды, система загадывает случайное число между цифрами от 0 до 1. Если система загадала 0 – мы устанавливаем новый префаб по оси X, а если 1 – то по оси Z. Вот и вся магия!

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

А вот и сам код скрипта playerFalls:
using UnityEngine; using System.Collections; public class playerFalls : MonoBehaviour < private Rigidbody rb; void Start() < rb = GetComponent(); > void Update() < RaycastHit hit; if(Physics.Raycast (transform.position, Vector3.down, out hit, 5f) && hit.transform.gameObject.tag == "Ground") < rb.useGravity = false; >else < rb.useGravity = true; >> >
Raycast – специальный луч на подобии лазера, который излучается по направлению к сцене. В случае, если луч отражается от объекта, он возвращает информацию об объекте, с которым столкнулся. И это очень круто, потому что именно так, посредством такого луча, направленного из центра сферы вниз, мы будем проверять, находимся ли мы на платформе Cube или нет (проверяем, имеет ли объект тэг «Ground»). И как только мы покинем регионы дорожного полотна, мы автоматом активируем параметр Gravity нашей сферы (помните, как мы заведомо отключили его в самом начале?), после чего сфера, под воздействием гравитации, рухнет вниз, ха-ха!
Этап-4: визуальный дизайн
Когда все работы по игровой механике закончены, в пору переходить к визуальной части проекта. Все таки геймплей – это хорошо, а приятный геймплей – еще лучше. И несмотря на то, что в самом начале мы обозначили графику, как далеко не самое главное, хочется все же привнести некоторую изюминку, добавив красок в создаваемую игру. После недолгих раздумий, в голову пришла следующая идея:

По замыслу, вы управляете автомобилем, несущимся по бескрайним морским просторам, спасаясь от надвигающего катаклизма. Промедление сродни смерти, так как платформы то и дело норовят опрокинуться в морскую пучину, увлекая игрока в бездну позора и разочарования. Плюс ко всему, время от времени, платформы начинают менять цвет, а автомобиль, самопроизвольно увеличивать скорость. Всё это призвано привнести в игру некое подобие «челленджа». Как и было сказано, за каждый удачно пройденный поворот или собранный кристалл, игрок вознаграждается «инкамом» — местным подобием зарплаты. Зарплату в последствии можно обменять в лавке на авто с более высоким «инкамом». Концепция подарила звучное название «Income Racer».
Все ассеты были смоделированы в Blender’е – бесплатном 3D редакторе. В нём же были созданы необходимые текстуры, впоследствии доведенные до приемлемого вида в Photoshop’е. Приятным моментом оказалось то, что Unity легко импортирует 3D модели из Blender’а, без лишней головной боли, делая процесс создания приятным и безболезненным.
Этап-5: полировка
Доводка проекта – те еще грабли, ведь всегда найдется место тому, что можно улучшить, или переделать. Зачастую, случается так, что именно на этапе полировки и доводки, процесс разработки значительно теряет во времени, а то и вовсе заходит в тупик. Причина заключается в том, что вы уже заметно подустали: игра вам кажется однообразной и недостаточно интересной. Иногда, под конец разработки, приходит откровение того, что вы способны на переделку игры с нуля, улучшив её как минимум в два раза! Отбросьте эти мысли и вспомните о плане, о том, с чего все начиналось. Лучше дополнять игру уже после релиза, путем выкатки обновлений, чем затягивать разработку на неопределенный срок. В противном случае, вы рискуете погубить проект, поставив на нём жирный крест. К примеру, на момент написания этих строк, игра даже не имела вступительного экрана. Причиной тому тот факт, что по плану я не мог выйти за рамки в 90 часов, отведенные на процесс разработки. Конечно, можно было бы потратить еще несколько часов на создание вступительного экрана, однако на то он и план, чтобы ему следовать. И это нормально, что некоторые моменты добавляются в игру уже после её релиза.
Последним, остается создать презентационные документы: краткое описание, видео, а также иконку игры. Этому этапу следует уделить как можно больше внимания, ведь именно по иконке, пользователи начинают судить ваш проект.
В итоге получилось то, что получилось. На всё про всё было затрачено чуть более 90 часов, что по меркам современного геймдева не так уж и много. По прошествии этого времени, игра была загружена в Play Market и выставлена на всеобщий суд, вот такая история! Если вам понравилась статья, или просто есть о чем поговорить, то добро пожаловать в комментарии. Буду рад ответить на ваши вопросы.
Делаем сами себе игру для Android
Недавно мы делали веб-игру про сбор пирамиды. Там мы использовали 3Д-движок и симуляцию физики. И в целом получилась залипательная веб-игра. Вот предыдущие этапы:
- Сделали трёхмерную браузерную игру, где нужно ставить блоки друг на друга и набрать как можно больше очков.
- Адаптировали игру под мобильные телефоны, чтобы тачскрин нормально обрабатывал все нажатия и жесты.
Ключевое слово — веб: игра работает только в браузере и только при наличии интернета. На этот раз мы превратим страницу с игрой в полноценное приложение для Android. При этом мы не будем пользоваться онлайн-конструкторами, а сделаем всё по-настоящему — в среде разработки и с кодом на Java.
- Подготовить файлы для упаковки в игру: скачать скрипты из интернета, перепривязать их к нашей игре на компьютере.
- Сделать новый проект в Android Studio.
- В проекте сделать WebView — это виртуальное окно браузера внутри приложения. В нём будет работать игра.
- Настроить WebView так, чтобы он поддерживал нашу игру и все нужные функции.
- Упаковать получившийся проект в виде приложения для Android.
Результат можно скачать сразу: вот приложение, которое получилось у нас таким нехитрым способом:
Подготовка
Главное, что нам понадобится из инструментов, — официальная среда разработки Android Studio. У нас есть про неё отдельная статья: что это такое, зачем нужно и как установить. Качаем с официального сайта и устанавливаем.
Так как наша игра должна работать без интернета, то это значит, что все ресурсы тоже должны быть доступны локально, прямо с телефона. В HTML-файле мы подключаем два внешних скрипта — их тоже нужно будет скачать:
Для этого копируем адрес скрипта из кода страницы, вставляем в браузер и сохраняем то, что открылось, как js-файл.
Скрипты кладём в ту же папку, что и остальные файлы с игрой. Вот что должно по итогу у нас получиться с файлами:

После этого исправляем пути к скриптам в html-файле, чтобы они подтягивались из той же папки, а не из интернета:
Сохраняем страницу и открываем её в браузере. Если мы всё сделали правильно, то «Пирамида» запустится как обычно — с красивой графикой и реакцией на нажатия.
Создаём новый проект в Android Studio
Запускаем Android Studio и выбираем Empty Activity:

После этого выбираем язык Java, а всё остальное оставляем без изменений:

Если это ваш первый запуск, программа начнёт качать разные служебные файлы — это нормально, нужно просто немного подождать.

Когда всё загрузится и запустится, перед нами появится окно с новой программой в Android Studio.
Добавляем файлы
Чтобы программа смогла загрузить в себя все файлы от игры, нам нужно создать в проекте специальную папку — assets — и скопировать в неё всё, что у нас есть. Для этого нужно пройти несколько неочевидных шагов:
- Создать папку внутри проекта в Android Studio.
- Найти папку на диске.
- Скопировать в папку все нужные файлы.
Создаём папку так: в левой верхней части щёлкаем правой кнопкой мыши по папке app и в появившемся меню выбираем New → Folder → Assets Folder:

Перед нами появится окно, которое спрашивает, к чему будет относиться папка. Ничего не меняем и просто нажимаем Finish:

Теперь щёлкаем правой кнопкой мыши на появившейся папке и выбираем Open in → Explorer:

Перед нами появится окно проводника с нашей папкой assets. Заходим в неё и копируем туда все игровые файлы, которые мы собрали в самом начале:

Смотрим в панель файлов Android Studio, чтобы убедиться, что всё получилось и система увидела наши файлы:

Пишем код
Нам было бы здорово видеть и дизайн, и код, поэтому выбираем слева в колонке файлов res → layouts → activity_main.xml и переключаем вид в режим Split в правом верхнем углу:

В этом же файле activity_main.xml есть блок, который начинается с команды . Среда разработки умная, поэтому, как только мы начнём писать код, она автоматически предложит нам создать новый блок. Нажимаем энтер, когда появится подсказка:

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

Нажимаем ⌘+S или Ctrl+S, чтобы всё сохранить .
Теперь переходим к другому файлу — MainActivity.java — и добавляем в него такой код:

setContentView(R.layout.activity_main); WebView webView=findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.loadUrl("javascript:addLayer(x, z, width, depth, direction)"); webView.loadUrl("javascript:generateBox(x, y, z, width, depth, falls)"); webView.loadUrl("javascript:addOverhang(x, z, width, depth)"); webView.loadUrl("javascript:cutBox(topLayer, overlap, size, delta)"); webView.loadUrl("javascript:init()"); webView.loadUrl("javascript:startGame()"); webView.loadUrl("javascript:eventHandler()"); webView.loadUrl("javascript:splitBlockAndAddNextOneIfOverlaps()"); webView.loadUrl("javascript:missedTheSpot()"); webView.loadUrl("javascript:animation(time)"); webView.loadUrl("javascript:updatePhysics(timePassed)"); webView.loadUrl("javascript:window.addEventListener()"); webView.loadUrl("file:///android_asset/index.html");
Смысл тут в том, что мы сначала создаём новый элемент — просмотрщик веб-контента, потом разрешаем ему выполнять скрипты, а затем перечисляем все функции, которые у нас объявлены в основном скрипте вместе с параметрами вызова. Это нужно для того, чтобы Java знала, что это можно выполнять.
Нажимаем Shift+F10, чтобы запустить приложение в эмуляторе, — видим, что справа появился виртуальный телефон с началом нашей игры, но ничего не двигается. Это связано с тем, что встроенный эмулятор плохо работает с трёхмерной графикой и не может показать всё, что мы от него хотим. Главное, зачем нам это было нужно, — убедиться, что программа нашла все наши файлы, загрузила их и скрипт тоже заработал.

Компилируем приложение
Если нам нужен apk-файл, который можно установить на телефон, чтобы проверить игру по-настоящему, нам надо скомпилировать весь проект. Для этого выбираем в верхнем меню Build → Build Bundle(s) / APK(s) → Build APK(s):

Когда всё будет готово, внизу появится уведомление, что файл готов. Нажимаем на locate, чтобы перейти к файлу в проводнике:

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

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Разработка мобильных игр на Unity в современных реалиях. URP, 2D Animation и все-все все на примере игры
Всем привет! Это снова Илья и сегодня мы поговорим о технической реализации мобильной игры в современных реалиях. Статья не претендует на уникальность, однако в ней вы можете найти для себя что-то полезное. А чтобы рассмотреть разработку на реальном проекте — мы возьмем реализацию нашей игры, которая на днях выходит в Soft-Launch.
Итак, запасаемся кофе, открываем Unity и погнали!
Базовая настройка проекта. URP и все-все-все.
Начнем с того, что мы работаем с URP (Universal Render Pipeline). Почему так? Потому что он проще в настройке и обладает более гибким контролем, чем стандартный рендер. Ну и добиться хорошей производительности на тапках исходя из этого — намного проще.
Стоит указать, что ниже пойдет речь о 2D игре. Для 3D игр подходы будут несколько отличаться, как и настройки.
Мы реализовали два уровня графики. Low Level — для деревянных смартфонов и High Level — для флагманов. Уровни графики подключаются при помощи Project Settings.
В нашем проекте стоят следующие настройки (для Quality уровней):
Настройки графики для пресета Low в Project Settings
Настройки пресета High
На что здесь следует обратить внимание:
- Texture Quality — качество текстур. Для High — мы берем полный размер текстур, для Low — Четверть. Можно еще внести Middle пресет с дополнительным уровнем.
- Resolution Scaling везде стоит 1 — мы берем это значение из URP Asset.
- VSync на Low уровне стоит отключить.
- Все что связано с реалтаймом — отключаем.
Теперь перейдем к настройкам самих URP Asset. На что следует обратить внимание:
Для разных уровней качества можно установить Render Scale — тем самым снижая разрешение для отрисовки. Также незабываем про Dynamic / Static батчинг.
Adaptive Performance
Отличная штука для автоматической подгонки производительности мобильных игр (в частности для Samsung-устройств):
Другие полезные настройки:
- Отключите 3D освещение, лайтмапы, тени и все что с этим связано.
- Используйте для сборки IL2CPP — ускорьте работу вашего кода.
- Используйте Color Space — Linear.
- По-возможности подключите multithreaded rendering.
Игровой фреймворк
Едем дальше. URP и другие настройки проекта сделали. Теперь настало время поговорить о нашем ядре проекта. Что оно включает в себя?
Само ядро фреймворка включает в себя:
- Игровые менеджеры для управления состояниями игры, аудио, переводов, работы с сетью, аналитикой, рекламными интеграциями и прочим.
- Базовые классы для интерфейсов (компоненты, базовые классы View).
- Классы для работы с контентом, сетью, шифрованием и др.
- Базовые классы для работы с логикой игры.
- Базовые классы для персонажей и пр.
- Утилитарные классы (Coroutine Provider, Unix Timestamp, Timed Event и пр.)
Зачем нужны менеджеры?
Они нужны нам для того, чтобы из контроллеров управлять состояниями и глобальными функциями (к примеру, аналитикой).
Хотя мы и используем внедрение зависимостей, менеджеры состояний реализованы в качестве синглтонов и могут быть (и по их назначению должны быть) инициализированы единожды. А дальше мы просто можем использовать их:
AnalyticsManager.Instance().SendEvent(«moreGamesRequested»);
А уже сам менеджер распределяет, в какие системы аналитики, как и зачем мы отправляем эвент.
Базовые классы.
Здесь все просто. Они включают в себя базовую логику для наследования. К примеру, класс BaseView и его интерфейс:
namespace GameFramework.UI.Base < using System; public interface IBaseView < public void ShowView(ViewAnimationOptions animationOptions = null, Action onComplete = null); public void HideView(ViewAnimationOptions animationOptions = null, Action onComplete = null); public void UpdateView(); >>
А дальше мы можем использовать его, к примеру таким образом:
Классы для работы с контентом, сетью, шифрованием
Ну здесь все просто и очевидно. Вообще, у нас реализовано несколько классов:
1) Классы шифрования (Base64, MD5, AES и пр.)
2) FileReader — считывающий, записывающий файл, с учетом кодировки, шифрования и других параметров. Также он умеет сразу сериализовать / десериализовать объект в нужном формате и с нужным шифрованием.
3) Network-классы, которые позволяют удобно работать с HTTP-запросами, работать с бандлами / адрессаблс и др.
Утилитарные классы
Здесь у нас хранятся полезные штуки, вроде Unix Time конвертера, а также костыли (вроде Coroutine Provider-а).
Unix Time Converter:
Костыль Coroutine-Provider:
namespace GameFramework.Utils < using System.Collections; using System.Collections.Generic; using UnityEngine; public class CoroutineProvider : MonoBehaviour < static CoroutineProvider _singleton; static Dictionary
Логика сцен
Наша игра — это по своей сути интерактивная история с различными мини-играми (поиск предметов, простенькие бои, крафтинг, найди пару, а также большое количество головоломок).
Каждая сцена — содержит в себе основной Installer, который помимо различных View, подключает логические блоки — своеобразные куски механик: