Как создать игру на Unity


Владимир Филимонов Эксперт в медицинских тренажерах VR на Unity, физических симуляциях и сетевых играх.
Сделать игру на Unity сможет даже начинающий кодер, который не знает С#. Большое количество обучающих материалов и активное комьюнити значительно облегчают первые этапы знакомства с движком и создание первого проекта. Вместе с ведущим разработчиком Unity Владимиром Филимоновым и преподавателем на курсе «Разработчик игр» разбираемся, почему писать код — не главное в геймдеве и какие базовые инструменты и ПО в играх нужно освоить, чтобы соорудить свою первую игру.
Что такое Unity
Unity — это и среда разработки, и игровой движок, с помощью которого создаются проекты для разных платформ: ПК, мобильных устройств, игровых консолей и интернет-платформ, — поэтому он называется кроссплатформенным. В Unity есть инструменты для создания объектов, их перемещения, работы с графикой, текстурами и звуком, поэтому сделать полноценную игру с его помощью можно даже в одиночку. Наглядный пример игры, созданной на Unity, которая поддерживает разные устройства, — Genshin Impact, успешный мультиплатформенный проект китайской студии miHoYo Limited. Более популярной стала ее мобильная версия, но пользователи могут войти в аккаунт, например, с компьютера и продолжить играть с того же момента, на котором остановились в мобильной версии. Кроме Genshin Impact, на Unity созданы такие известные проекты, как Hearthstone, Outlast, Cuphead, Pokemon GO и многие другие.

Освойте профессию «Разработчик игр на Unity»
Разработчик игр на Unity
Все главные навыки разработчика игр на одном курсе. Вы освоите все этапы геймдизайна, научитесь программировать на С# и создадите 7 игр во время курса.

Профессия / 18 месяцев
Разработчик игр на Unity
Создавайте виртуальные миры
5 399 ₽/мес 9 817 ₽/мес

- имеет практически неограниченный бесплатный функционал;
- не требует глубокого знания языков программирования для создания первых простых проектов;
- имеет многочисленное и активное сообщество, в котором можно найти ответ на любой вопрос, потому что среди такого большого количества людей кто-то обязательно уже сталкивался с вашей проблемой.
Читайте также Как скачать и установить Unity
Как создать простую игру
При создании собственного проекта важно помнить, что разработка кода — это примерно 20% игры; гораздо большее значение в ней имеют другие аспекты:
- Геймплей — это общее понятие взаимодействия игрока с игровым миром, которое определяет его действия (бежать вперед, преодолевать препятствия, стрелять по мишеням, обгонять других) и цели (прийти первым к финишу, выбить 10 из 10, победить врага в бою, собрать как можно больше монет). Геймплей напрямую связан с жанром игры, так как у каждого из них есть специфичный набор правил и механик.
- Игровые механики— конкретные элементы взаимодействия с игрой, которые входят в состав геймплея. Стрельба — это одна механика, сражение на мечах — другая, гонка — третья. Одна игра может сочетать в себе десятки таких механик.
- Сюжет— это развитие действия в игре; он одинаково важен и для масштабных AAA-проектов, и для небольших, но глубоких инди-игр. Сюжет должен затянуть игрока, рассказать ему историю, а также развивать персонажей, чтобы они не оставались однобокими и раскрывались для игрока с новых сторон.
- Персонажи — в них важны и дизайн, и характер. Удачно проработанный персонаж обладает узнаваемыми особенностями поведения, интересной историей, а еще для полного погружения он должен иметь что-то общее с игроком, что зацепит его и заставит сопереживать. На эту тему Unity разработали гайд «Пять типов привлекательных игровых персонажей», чтобы у новичков получалось сделать игрового персонажа правдоподобным.
- Дизайн уровней— это внешний вид игры, цветовые решения, общая стилистика объектов, фона, персонажей, предметов, которая создает определенное настроение. В помощь начинающим разработчикам Unity опубликовали в своем блоге «Советы по дизайну уровней вашей первой видеоигры».
- Баланс — это соотношение характеристик разных объектов, он тоже отвечает за увлеченность игрока. Например, если меч в игре может наносить объекту 3 единицы урона, а объект имеет всего 3 HP (hit points — величина, обозначающая максимальный урон), то его можно уничтожить с первого раза, и играть будет слишком легко. Если объект имеет 30 HP, то игроку придется нанести 10 ударов, чтобы его уничтожить. Такое уже подходит скорее для босса, например на первом или втором уровне. Разработчику важно грамотно распределить эти величины, чтобы игра была увлекательной и бросала игроку вызовы.

Разработчик игр на Unity – одна
из самых творческих профессий в IT. Создайте виртуальные миры уже через полгода обучения
Перед созданием игры важно продумать все эти моменты и представить общую картину, а также найти референсы, на которые можно ориентироваться, продумать опорные точки сюжета и механики. Для создания игры именно на Unity также пригодится понимание некоторых базовых терминов, с которыми постоянно придется сталкиваться в процессе разработки:
- Ассет (Asset)— готовый компонент, который можно использовать для создания своих проектов. Это могут быть элемент интерфейса в игре, текстура, фигурка персонажа, шрифт или звук.
- Игровой объект (GameObject)— это любой ассет, который используется в игровой сцене. Например, изображение монетки, сам ее внешний вид — это ассет, а пять монет, которые должен подобрать персонаж в процессе прохождения уровня — это пять игровых объектов. Сам персонаж при этом тоже станет игровым объектом.
- Компоненты (Components) — часть игрового объекта, отвечающая за его поведение в процессе игры: перемещение или реакцию на определенные триггеры.
- Скрипт (Script)— код на C#, в котором прописаны конкретные условия работы компонента.
Установка Unity занимает 5–10 минут. Для этого нужно зайти на официальный сайт проекта и выбрать бесплатный тариф для физических лиц — Personal. Его будет достаточно для самостоятельного изучения Unity и создания первой игры. Еще один бесплатный тариф — студенческий, но он подойдет тем, кто зарегистрирован на GitHub и может подтвердить свой ученический статус.
После нажатия кнопки «Начать» откроется Unity Store. Для новых пользователей в нем есть вариант установки движка с обучающим руководством для начинающих. С помощью кнопки «Начните здесь» скачивается установщик UnityHubSetup.exe, который запускается как любой другой установщик: нужно просто открыть файл, принять условия пользовательского соглашения и нажать кнопку «Установить».
Русского языка в настройках нет, так что придется совершенствовать технический английский. Всего Unity занимает 11,3 Гб,поэтому перед установкой лучше проверить свободное место на диске и почистить его при необходимости.
Следующий шаг — создание Unity ID. Можно регистрироваться с помощью почты или использовать предложенные аккаунты, например Google или Apple. Важно поставить первые две галочки: согласие с условиями использования Unity и признание политики конфиденциальности. Третья галочка — это согласие на маркетинговые рассылки, ее ставить не обязательно.

После регистрации Unity предложит создать тестовый проект Microgame. На выбор предлагается пять шаблонов:
- LEGO Microgame;
- шутер от первого лица;
- картинг;
- платформер;
- пустой 3D-шаблон.
Можно выбрать любой из них и посмотреть, как работает создание игры в конкретном жанре. Обучающий материал пошагово демонстрирует назначение различных окон в интерфейсе и принцип работы с элементами игры: как заставить двигаться персонажей, поменять текстуру объекта или его форму. В обучении окно Scene, в котором происходит вся работа с элементами, уже заполнено различными объектами, но при создании проекта с нуля оно будет пустым.
Создание проекта
После обучения можно перейти к созданию своей первой игры на Unity с помощью кнопки NEW в меню проектов.
Новому проекту присваивается имя, выбираются место хранения на диске и темплейт — то есть шаблон для разработки, внешний вид и функционал которого зависит от количества измерений в игре. Проще начинать с 2D-проектов, так как для этого формата создано больше готовых ассетов. Конечно, можно сразу начать делать 3D-игры, но в этом случае многие элементы и анимации придется самостоятельно создавать с нуля или выделять бюджет на то, чтобы делегировать эту часть работы другим специалистам.
Настройка интерфейса
В стандартном интерфейсе проекта шесть элементов рабочей области:

- Верхняя панель инструментов— в ней находятся стандартные вкладки File, Edit, Help, как во многих других интерфейсах, а также вкладки Assets, GameObject, Components и Window.
- Scene — окно сцены, в котором выстраивается игровое пространство (элементы игрового мира, текстуры, фигурки персонажей и прочее).
- Games — это окно игры, в котором можно посмотреть глазами пользователя, как будут двигаться элементы и работать игровые механики.
- Hierarchy — окно иерархии, в нем перечислен список всех элементов (GameObject), которые помещены в окно Scene.
- Project — это система папок, в которых хранятся ассеты по категориям (текстуры, шрифты, звуки и т.д.).
- Inspector — окно для изменения элементов игры, их размера, цвета, положения в пространстве и других характеристик.
Добавление объекта
Объекты на экран Scene можно добавить из Asset Store. Для этого на панели инструментов нужно кликнуть на вкладку Window –> General –> Asset Store.
В строке поиска можно по названиям найти нужные компоненты, например, сет Free Platform Game Assets.
Как и другие ассеты, он загружается с помощью кнопки Import.
Перед загрузкой появится список всех компонентов, которые содержит этот пакет; некоторые из них можно исключить. Если в списке есть персонажи, текстуры или другие элементы, которые вам не нужны, можно просто снять галочки, и пакет загрузится без них.
После установки все ассеты будут доступны в окне Project. Теперь можно комбинировать и перемещать эти объекты, менять их форму, причем сделать это можно с помощью мыши или горячих клавиш, не написав ни одной строчки кода. Например, из перечня платформ самых разных видов можно выбрать одну и мышкой перетащить ее в рабочую область.
Шаг 2. Перенести в область Scene

Работа со скриптами
За поведение игровых объектов отвечают присоединенные к ним компоненты (Components). Базовый компонент любого объекта — Transform, он отвечает за положение элемента в окне Scene, возможность поворачивать и масштабировать его. К базовому компоненту можно добавить, например, Renderer, который меняет цвет, или RigidBody, который отвечает за массу и физику объекта. Но кроме базовых компонентов, объектам можно задавать особые условия, и для этого как раз используются скрипты.
Создать новый скрипт можно в окне Project, кликнув мышкой на Assets –> Create –> C# Script.
Двойным кликом мыши скрипт открывается в текстовом редакторе. Скрипты, как и все остальное в Unity, прописываются на С#, так что для создания сложных проектов разработчикам все же придется освоить этот язык программирования.
Базовые элементы скриптов — это:
- using — элемент в коде, который подключает библиотеки;
- public class — в этой строке обычно прописан класс MonoBehaviour, он содержит набор функций, необходимых для работы скрипта;
- void — те самые функции, с их помощью прописываются действия, происходящие в игре.
Рассмотрим, например, функцию start. Любое действие в ней произойдет только один раз, когда запустится игра. Пропишем здесь print (“Hi”).
И можно заметить, что в консоли это слово выводится один раз.
Функция update — повторяющаяся, ее можно использовать, например, для передвижения объекта. Для этого в скрипте задается переменная int i = 0, она выводится на экран с помощью функции print (i) и увеличивается на одну единицу за каждый шаг с помощью i++.
В консоли можно будет заметить, что апдейт действительно срабатывает каждый фрейм и объект, к которому применен этот скрипт, плавно движется.
Настройка триггеров
Для понимания сути триггеров важно усвоить, что такое коллайдер (Collider). Это компонент, который присваивается объекту в пространстве игры, задает форму и делает его твердым, недоступным для прохождения сквозь него. Например, если мы разместим монетку в 2D-пространстве и захотим сделать так, чтобы она упала на платформу, то без использования компонента Collider ничего не получится — монетка пролетит сквозь платформу.
Поэтому обоим объектам необходимо присвоить компонент Box Collider 2D — это тонкая зеленая линия, которая обводит элементы по контуру, и за счет этой рамки они становятся твердыми, то есть один не может пройти сквозь другой.
Так объекты обязательно соприкоснутся и монета встанет на платформу.
Триггер (Trigger) — это пространство на карте, при попадании объекта в которое происходит действие; он тоже обводит объект или область в пространстве по краям. По сути, это тот же коллайдер, только триггер позволяет объектам проходить внутрь этой области. Представьте, что на ту же самую платформу вместе с коллайдером наброшен триггер, и при попадании персонажа внутрь триггерной области активируется телепорт — персонажа перебрасывает в другую точку карты.
Чтобы создать триггер, нужно накинуть тот же самый компонент коллайдера, но поставить галочку Is Trigger.

Триггеры распознают три варианта взаимодействия области на карте и объекта:
- OnTriggerEnter — объект зашел в зону;
- OnTriggerStay — объект находится в зоне;
- OnTriggerExit — объект покинул зону.
Что дальше?
Освоить интерфейс Unity довольно легко, в интернете есть разные гайды на тему того, как сделать это действительно быстро. Например, видео «Я сделал игру на Unity за неделю» или обучающий мини-курс «Как создать RPG за час». Можно изучать геймдев самостоятельно или начать обучение на курсе — это ускорит процесс и даст более заметные результаты.
Для работы со скриптами и создания более сложных механик разработчикам в любом случае понадобится С#, так что к его изучению вы тоже рано или поздно придете. Но в отличие от Unity, по C# нет в свободном доступе такого большого количества актуальных и понятных гайдов, так что в целях экономии времени и сил лучше записаться на курс «Разработчик игр на Unity», где все знания упакованы в структурированные блоки и сбалансированы с практикой на тренажерах.
Как я делал руку с картами для своей карточной игры
Зона, с которой игрок чаще всего взаимодействует в карточной игре — это его рука (не путать с рукой в играх с 18+ контентом). Рука — это набор карт, которые игрок может разыграть в текущий ход. И раз это одно из самых важных мест, я решил уже на этапе прототипа сделать руку приятной и красивой.
Дисклеймер: я тут описываю свой говнокод. Программировать я совсем не умею, так что не советую использовать как инструкцию.
Вот как раз во время работы с рукой (не путать с «во время работы рукой») я понял отличие качественной игры от поделки на уровне прототипа для тестирования геймплея. Все дело в мелочах и деталях. Посмотрите, как ведут себя карты в руке в Slay the Spire:
Теперь посмотрите на те же карты на видосе у чела, который пишет в названии ролика, что он сделал Slay the Spire за неделю (9:11):
Теперь у меня это название вызывает горький смех, потому что как раз из-за таких небольших фишек с анимациями запрограммировать всё из Slay the Spire не удастся за неделю, даже при условии, что у тебя будет готов абсолютно весь арт, геймдизайн и другой контент.
Ключевая разница в этих двух примерах: то, как карты реагируют на наведение на них курсора мыши. В оригинале карта выходит на передний фон и красиво скейлится, а остальные карты разлетаются в сторону от нее. В копии карта просто поднимается и даже не вылезает на передний фон. Именно об это я споткнулся, когда захотел сделать для руки красивые анимации.
Как я делал руку с картами
Первую руку я сделал по туториалу, с которого делал первый прототип. В нём за формирование руки отвечал компонент Grid, который расставляет объекты по сетке. Grid лишает вас необходимости писать код, который отвечает за расстановку карт: вы просто задаете настройки и карты сами встают ровно при любом количестве, когда попадают в нужный родительский объект.

Проблема с Grid была в том, что делалось это некрасиво: карты телепортировались в сетку, а мне хотелось, чтобы они плавно переходили.
Недолго погуглив, я нашёл в Ассет Сторе бесплатный ассет Smooth Grid. Там были желанные плавные переходы. Если я вытаскивал карту, она потом вставала в конец — ну да и ладно, решил я.

Проблемы со Smooth Grid появились, когда я решил сделать руку похожей на руку в реальной жизни и в других карточных играх — чтобы карты слегка наезжали друг на друга — и после этого стал думать, как мне сделать выделение карты по наведению курсора. Сначала карты просто не хотели выезжать. Когда я разобрался с выездом, понял, что карта не хочет выходить на передний план. Всплыла проблема с тем, что эта плавная сетка перемещала карты влево или вправо в зависимости от положения объекта с картой в инспекторе. А значит, если я буду выводить карту на передний план с помощью перемещения в инспекторе, карта будет перескакивать со своей позиции в самую крайнюю в руке. Такое мне точно не подходило.
Я понял, что в 2D в Unity не было способов перетащить объект на задний и передний план кроме свойства Sorting Layer. Вот только применить его можно только к объектам с компонентом Sprite Renderer. Он отвечает, например, за то, чтобы у карточки выводилась нужная картинка. А у меня все объекты имели компонент Image — я выводил изображение карточки с помощью него.
Так вот, чтобы выводить карточку на передний план, мне нужно было менять компонент Image на компонент Sprite. И это привело к своим сюрпризам. Оказывается, все объекты внутри Canvas с компонентом Image будут перекрывать любой другой объект. И когда я создаю объект Background, который задумывал как фон, он перекрывает спрайты карточек, и поверх фона ничего не видно. И это довольно логично: любой объект внутри Canvas Unity распознает как часть интерфейса: а интерфейс как бы должен быть поверх всего остального в игре. Но…на осознание этих правил у меня ушло много времени. А еще много времени на то, чтобы разобраться, как выставить настройки у спрайтов, поправить поехавшую камеру и сделать кучу мелких действий.
Следующее открытие: Event Trigger, компонент, с помощью которого я делал выведение карточек на передний план при наведении мыши и разыгрывании карточек, не хотел работать со спрайтами. Один и тот же скрипт у меня работал на объекте с Image и переставал работать на объекте со Sprite Renderer. Оказалось, есть еще один способ регистрировать наведение мышки: с помощью методов MouseEnter, MouseExit и MouseOver.
Дальше меня ждали новые проблемы. Я использовал метод Lerp, чтобы карточки красиво залетали в руку и красиво выдвигались, когда наводишь на них курсор. Все отлично работало ровно до тех пор, пока я не совмещал анимации карточек с их добавлением в Smooth Grid. Тогда начиналась котовасия.
Дело в том, что Smooth Grid тоже построен на Lerp. А Lerp — это такая функция, которая как резиночка тянет объект на родительское место. И вот проблема была в том, что Lerp в сетке и мой Lerp спорили между собой, а карточки в итоге трясло и кидало в разные стороны. Я пытался это решить попеременным отключением Lerp’ов — не сработало. Все начинало ехать еще больше.
В итоге пришлось отказаться от компонента Grid совсем: и от Smooth, и от обычного. Я сам сделал простенький вывод на нужную позицию с помощью цикла for, максимально костыльно.

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

Не напоминает ли это вам этот момент из «Кролика ДжоДжо» (0:18):
Хотелось бы конечно сделать так же сочно, как в Slay the Spire, но это капец сколько ещё ковыряться. Вообще при разработке стараюсь максимально отсекать всё лишнее. Например, когда я понял сейчас, что надо много всего перепиливать, я отсек вообще всю логику, которая не нужна была для той задачи, которую я поставил себе здесь, в телеге. Этим путём я следую и при разработке части игры для трейлера: максимальный говнокод (даже по моим меркам, а я тот ещё программист), максимум бутафорских штук. Например, у меня карточки тупо вылазят из края экрана, а там они изначально лежат перед запуском экрана.
Если поделитесь в комментариях гайдами и туториалами, как можно лучше сделать руку с картами, буду очень благодарен.
Этот пост входит в цикл постов про игру, которую я потихоньку делаю уже несколько месяцев. Я делюсь всем производственным процессом: какие решения я принимаю в разработке, геймдизайне, интерфейсе, арте и других сферах. В моем телеграм-канале вы можете посмотреть другие посты и узнать, когда ждать следующие: @nigylamchan.
Карточная игра на Unity. Динамическая колода

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

Компоненты игральной колоды карт
В игральной колоде содержится всего 52 карты с 13 картами каждой из 4 разных мастей. Чтобы создать пригодный для использования код, нам необходимо создать эти 4 масти, закругленную прямоугольную основу карты и дизайн обложки карт.
Дизайном обложки у карты может быть любой абстрактный рисунок, и существует множество способов создать его. Мы сделаем простой бесшовный узор, который для создания дизайна потом замостит поверхность. Никакого специального дизайна для тузов (A), королей (K), дам (Q) и валетов (J) у нас не будет.
Альтернативные решения
Перед тем как начать, я должен упомянуть, что существуют более простые решения, которые мы могли бы использовать для создания колоды карт. Некоторые из них перечислены ниже.
- Очевидным является использование для всех эскизов предварительно отрисованного арта.
- Менее очевидно использовать шрифт, который содержит все необходимые символы. Вышеупомянутый шрифт мы также можем превратить в битмаповый, чтобы уменьшить число вызовов отрисовки и повысить производительность.
Решение на основе шрифтов самое быстрое и простое, если вы ходите делать быстрые прототипы.
Создание текстур во время исполнения
Первым шагом изучим как создать Texture2D с использованием кода, который потом будет использован для создания Sprite в Unity. Следующий код показывает создание пустой текстуры 256×256.
Texture2D texture = new Texture2D(256, 256, TextureFormat.ARGB4444, false); texture.filterMode=FilterMode.Trilinear; texture.wrapMode=TextureWrapMode.Clamp; texture.Apply();
Идея в том, чтобы нарисовать все эскизы до того, как мы будем использовать метод Apply. Мы можем нанести эскиз на текстуру пиксель за пикселем, используя метод SetPixel, как показано ниже.
texture.SetPixel(x, y, Color.white);
Например, если мы хотели заполнить всю текстуру цветом, мы могли бы использовать метод следующим образом.
private void PaintRectangle(Texture2D texture, Rect rectBounds, Color color) < for (int i=(int)rectBounds.x;i> > // PaintRectangle(texture,new Rect(0,0,256,256),Color.red);
Как только мы создали Texture2D, мы можем использовать ее для создания Sprite, выводимого на экран.
Sprite sprite = Sprite.Create(texture, new Rect(0.0f, 0.0f, texture.width, texture.height), new Vector2(0.5f, 0.5f),1);
Сложной частью всего этого является создание на текстуре нужных эскизов.
Создание фигуры для червовой масти
Когда дело доходит до создания фигуры для червей, мы можем использовать несколько различных подходов, среди которых есть как сложные уравнения, так и простое смешение фигур. Как показано ниже мы будем использовать метод смешения фигур, в частности, тот что с треугольником.

Как вы заметили, мы можем использовать два круга и квадрат или треугольник, чтобы создать базовую фигуру сердца. Это означает, что у сердца не будет тех самых красивых изгибов, но оно идеально подойдет для нашей цели.
Рисование круга
Давайте освежим некоторые уравнения, чтобы нарисовать круг. Для круга с центром в начале координат и радиусом r уравнение для точки (x, y) на окружности имеет вид x 2 + y 2 = r 2 . Теперь, если центр круга находится в точке (h, k), уравнение становится (x-h) 2 + (y-k) 2 = r 2 . Таким образом, если у нас есть ограничивающий прямоугольник, то мы можем перебрать все точки внутри этого прямоугольника и определить, какие из них попадают в круг, а какие нет. Основываясь на этом понимании, мы можем с легкостью создать метод PaintCircle, как показано ниже.
private void PaintCircle(Texture2D texture,float radius, Vector2 midPoint, Color color) < Rect circleBounds=new Rect(); circleBounds.x=Mathf.Clamp(midPoint.x-(radius),0,resolution); circleBounds.y=Mathf.Clamp(midPoint.y-(radius),0,resolution); circleBounds.width=Mathf.Clamp(2*radius,0,resolution); circleBounds.height=Mathf.Clamp(2*radius,0,resolution); float iValue; for (int i=(int)circleBounds.x;i> > > PaintCircle(texture,radius,mid,Color.red);
Как только у нас есть метод PaintCircle, мы можем продолжить создание фигуры червей как показано ниже.
void PaintHearts(Texture2D texture) < //2 circles on top float radius =resolution*0.26f; Vector2 mid=new Vector2(radius,resolution-radius); PaintCircle(texture,radius,mid,Color.red); mid=new Vector2(resolution-radius,resolution-radius); PaintCircle(texture,radius,mid,Color.red); //triangle at bottom float width=resolution*0.58f; int endJ=(int)(resolution*0.65f); int startJ=(int)(resolution*0.1f); float delta=(width/endJ); float midI=resolution*0.5f; for (int i=0;i> > >
Переменная resolution является шириной и высотой текстуры.
Создание фигуры для бубновой масти
Мы обсудим два способа нарисовать бубны.
Рисование простого ромба
Проще всего расширить код использованный для треугольника и добавить перевернутый треугольник наверху, чтобы создать необходимую фигуру как показано ниже.
void PaintDiamond(Texture2D texture)< float width=resolution*0.35f; for (int i=0;i(midI-(delta*j))&&i(midI-(delta*j))&&i <(midI+(delta*j)))< isValid=true; >> return isValid; > PaintDiamond(texture);
Рисование изогнутого ромба
Второй способ – это использовать еще одно уравнение для создания улучшенной, изогнутой версии ромба. Мы будем использовать его для создания узора на обратной стороне нашей карты. Уравнение для круга получается из исходного уравнения для эллипса, оно выглядит как (x/a) 2 + (y/b) 2 = r 2 .
Это уравнение совпадает с уравнением окружности, когда переменные a и b равны 1. Затем уравнение эллипса можно расширить в уравнение суперэллипса для аналогичных фигур, просто изменив степень, (x/a) n + (y/b) n = r n . Поэтому когда n равно 2, у нас есть эллипс, а для других значений n у нас будут разные фигуры, одной из которых является наш ромб. Мы можем использовать подход, использованный для получения метода PaintCircle и получить новый метод PaintDiamond.
private void PaintDiamond(Texture2D texture, Rect rectBounds, Vector2 midPoint, Color color, float n=0.8f) < float iValue; int a=(int)(rectBounds.width/2); int b=(int)(rectBounds.height/2); float nRoot=1/n; float delta; float partialOne; rectBounds.width=Mathf.Clamp(rectBounds.x+rectBounds.width,0,resolution); rectBounds.height=Mathf.Clamp(rectBounds.y+rectBounds.height,0,resolution); rectBounds.x=Mathf.Clamp(rectBounds.x,0,resolution); rectBounds.y=Mathf.Clamp(rectBounds.y,0,resolution); for (int i=(int)rectBounds.x;i> > >
Рисование закругленного прямоугольника
Изменяя значение n, это же уравнение можно использовать для создания базовой формы в виде закругленного прямоугольника для нашей карты.
private void PaintRoundedRectangle(Texture2D texture) < for (int i=0;ireturn isValid; >
Рисование бесшовного узора
Используя этот метод PaintDiamond, мы можем нарисовать пять ромбов и создать бесшовный узор для задней стороны нашей карты.

Код для рисования бесшовного узора будет такой, как ниже.
private void PaintTilingDesign(Texture2D texture, int tileResolution) < Vector2 mid=new Vector2(tileResolution/2,tileResolution/2); float size=0.6f*tileResolution; PaintDiamond(texture,new Rect(mid.x-size/2,mid.y-size/2,size,size),mid,Color.red); mid=new Vector2(0,0); PaintDiamond(texture,new Rect(mid.x-size/2,mid.y-size/2,size,size),mid,Color.red); mid=new Vector2(tileResolution,0); PaintDiamond(texture,new Rect(mid.x-size/2,mid.y-size/2,size,size),mid,Color.red); mid=new Vector2(tileResolution,tileResolution); PaintDiamond(texture,new Rect(mid.x-size/2,mid.y-size/2,size,size),mid,Color.red); mid=new Vector2(0,tileResolution); PaintDiamond(texture,new Rect(mid.x-size/2,mid.y-size/2,size,size),mid,Color.red); >
Создание фигуры для пиковой масти
Фигура для пик – это просто вертикальное отражение фигуры червей, наложенное на базовую фигуру. Эта базовая фигура останется одинаковой для треф. На рисунке ниже показано, как для создания базовой фигуры мы можем использовать два круга.

Метод PaintSpades будет таков, как показано ниже.
void PaintSpades(Texture2D texture) < //2 круга посередине float radius =resolution*0.26f; Vector2 mid=new Vector2(radius,resolution-2.2f*radius); PaintCircle(texture,radius,mid,Color.black); mid=new Vector2(resolution-radius,resolution-2.2f*radius); PaintCircle(texture,radius,mid,Color.black); //треугольник наверху float width=resolution*0.49f; int startJ=(int)(resolution*0.52f); float delta=(width/(resolution-startJ)); float midI=resolution*0.5f; int alteredJ; radius=resolution*0.5f; float midJ=resolution*0.42f; float iValue; for (int i=0;i> //ножка for (int k=0;kmid.x+iValue) < mid=new Vector2(resolution,midJ); iValue=(Mathf.Sqrt(radius*radius-((k-mid.y)*(k-mid.y))));//+mid.x; if(i > > > >
Создание фигуры для масти треф
В этом месте я уверен, что вы можете самостоятельно догадаться, как просто стало сделать фигуру для треф. Нам нужны всего лишь две окружности и базовая фигура, которую мы создали для пик.

Метод PaintClubs будет таков, как показано ниже.
void PaintClubs(Texture2D texture) < int radius=(int)(resolution*0.24f); //3 круга Vector2 mid=new Vector2(resolution*0.5f,resolution-radius); PaintCircle(texture,radius,mid,Color.black); mid=new Vector2(resolution*0.25f,resolution-(2.5f*radius)); PaintCircle(texture,radius,mid,Color.black); mid=new Vector2(resolution*0.75f,resolution-(2.5f*radius)); PaintCircle(texture,radius,mid,Color.black); //ножка radius=(int)(resolution*0.5f); float midY=resolution*0.42f; int stalkHeightJ=(int)(resolution*0.65f); float iValue; for (int i=0;i> > > >
Упаковка текстур
Если вы изучите исходные файлы Unity для этого проекта, вы найдете класс TextureManager, который выполняет всю тяжелую работу. После того как мы создали все необходимые текстуры, класс TextureManager использует метод PackTextures, чтобы объединить их в одну текстуру, тем самым уменьшая количество вызовов отрисовки, требуемых при использовании этих фигур.
Rect[] packedAssets=packedTexture.PackTextures(allGraphics,1);
Используя массив packAssets, мы можем получить ограничивающие рамки отдельных текстур из основной текстуры с именем packTexture.
public Rect GetTextureRectByName(string textureName)< textureName=textureName.ToLower(); int textureIndex; Rect textureRect=new Rect(0,0,0,0); if(textureDict.TryGetValue(textureName, out textureIndex))< textureRect=ConvertUVToTextureCoordinates(packedAssets[textureIndex]); >else < Debug.Log("no such texture "+textureName); >return textureRect; > private Rect ConvertUVToTextureCoordinates(Rect rect)
Заключение
Создав все необходимые компоненты, мы можем приступить к созданию нашей колоды карт, так как это просто вопрос правильного расположения фигур. Для составления карт мы можем использовать пользовательский интерфейс Unity, или можно создавать карты в виде отдельных текстур. Вы можете изучить пример кода, чтобы понять, как для создания макетов карт я использовал первый из способов.
Мы можем использовать этот же метод для создания любого динамического арта во время выполнения в Unity. Создание графики во время выполнения – это операция, требующая высокой производительности, но ее можно произвести только один раз, если мы эффективно сохраним и повторно используем эти текстуры. Путем упаковки динамически созданных ресурсов в одиночную текстуру, мы также получаем преимущества от использования атласа текстур.
Теперь, когда у нас есть колода игральных карт, дайте мне знать, какие игры вы планируете создать с ее помощью.
Понравилась статья? Поделиться с друзьями:
Переводит для Вас самые интересные статьи про разработку игр. По образованию физик-программист. Техническими переводами начала подрабатывать еще на старших курсах и постепенно это переросло в основное занятие. Интересуется гуманитарными технологиями, пробует себя в журналистике.
Добавить комментарий Отменить ответ
- CoreMission в:
- Telegram
- YouTube
- Календарь: даты выхода игр
- Календарь: игровые ивенты
- Крутые игры на ПК
- Пойдет ли игра на ПК?
- Игры для слабого ноутбука
- Как стать киберспортсменом?
- Коды на The Sims 4
- Все дополнения Sims 4
- Разработчики инди-игр
- Всё про “читы” в играх
- Читы для CS: GO
- Как создать игру самому?
- Как стать разработчиком игр?
- Референсы для художников
- Символы для ников
- Время прохождения игр
- Похожие игры
- Карта сайта
Как создать простую 2D-игру на Unity
На создание игры обычно уходит много времени и сил, но движок Unity значительно облегчает процесс. И в 2D-, и в 3D-играх.



Евгений Кучерявый
Пишет о программировании, в свободное время создаёт игры. Мечтает открыть свою студию и выпускать ламповые RPG.
Сохранитесь и подпишитесь: наш Telegram-канал «Чекпоинт» — уютное место, где мы рассказываем об играх и о том, как они создаются.
С помощью Unity сделаны такие игры, как:
- Outlast;
- Hearthstone;
- Cuphead;
- Rust;
- Firewatch;
- Inside;
- Cities: Skylines и другие.
Из статьи вы узнаете, из каких компонентов создаётся игра и как написать свой первый проект. Вот такие нас ждут этапы:
- Создаем проект в Unity.
- Добавляем первый объект.
- Пишем скрипт.
- Назначаем триггер.
Почему Unity
Unity в несколько раз ускоряет разработку, потому что берёт на себя физику, графику, анимацию и работу со звуком. На движке делают игры практически для всех платформ. Причём пользуются им не только инди-разработчики, но и крупные студии.
Как именно пользоваться движком Unity и создавать крутые проекты, — мы учим на курсе «Разработчик игр с 0 до PRO».
Как установить Unity
Скачиваем Unity на официальном сайте. Новичкам достаточно бесплатного тарифа Personal.
Последняя версия движка может не поддерживаться на старых компьютерах. Если так, то подходящую стоит поискать в архиве версий. Игра для этой статьи написана на Unity 5.5.0f3. Интерфейс более поздних версий не сильно менялся, поэтому руководство подойдёт и для них.
Игры на старых версиях движка потребляют больше ресурсов устройства при меньшей сложности. Кроме того, в них встречаются уязвимости и ошибки. Но главная проблема в том, что некоторые платформы больше не поддерживают игры, созданные на старых версиях, так как было изменено API.
- Запустите установщик и следуйте инструкциям.
Кроме самого движка, вам предложат установить Microsoft Visual Studio — интегрированную среду разработки. Это лучшие возможности по работе со скриптами в Unity, но она занимает много места на диске. - Если Microsoft Visual Studio установлена или используется другой редактор кода, уберите галочку. Альтернативами могут быть Microsoft Visual Studio Code (более лёгкая версия Visual Studio) или MonoDevelop — встроенный редактор Unity.
- Когда установка завершится, пора приступать к разработке своей первой игры.
Как создать проект в Unity
Запустите Unity и нажмите кнопку New или New project.

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

На подготовку файлов уйдёт какое-то время, затем появится окно редактора Unity:

На слабых компьютерах может появляться розовый фон и следующая ошибка:
SceneView Selected shader is expected to have 7 passes
Чтобы устранить ее, нажмите кнопку Gizmos, а потом уберите галочку с пункта Selection Outline:

Затем зайдите в пункт меню Edit и в подменю Graphics Emulation выберите Shader Model 2:

Проект создан, можно начинать работу. Полный код игры вы найдете в репозитории на GitHub. Там же есть все ассеты и скрипты.
Как добавить объект в Unity
1. Перетащите ассет из поля Assets внизу экрана.
Ассетами называют компоненты, которые нужны для создания игры. Для удобства поместите их в отдельные папки:
- Scenes — локации в игре.
- Scripts — скрипты на выбранном вами языке программирования, с помощью которых устроена механика игры.
- Sprites — двухмерные изображения предметов, персонажей, фонов и так далее.
- Prefabs — заготовки игровых объектов.
СПРАВКА
Создать папки и добавить файлы можно как в Unity, так и просто в обозревателе Windows. Создавать скрипты лучше с помощью движка, потому что он будет автоматически добавлять заготовку кода (подробнее об этом ниже).
2. Скопируйте несколько картинок игровых объектов
Теперь перетащите нужный спрайт из поля с ассетами в окно сцены. Чтобы сквозь него не пролетали другие объекты, добавьте к нему компонент типа Collider 2D из категории Physics 2D. Выбирайте тот тип, который соответствует форме спрайта: например, Circle Collider 2D (если это шар) или Box Collider 2D (если квадрат).

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