Недавно мы рассказали о том, как научиться разработке игр на Unity. Продолжим тему на практике и покажем, как новичку создать на этой платформе первую 2D-игру.
Примечание Если вы хотите получить более систематическое образование в области разработки игр, мы рекомендуем рассмотреть факультет разработки игр онлайн-университета GeekBrains.
Двумерные игры сравнительно просты: для них не требуется сложных 3D-моделей, программный код по сравнению с 3D-проектами выглядит понятнее. Такие игры популярны как на десктопах, так и на мобильных устройствах. Unity также позволяет разрабатывать игры и для браузеров.
За последние годы вышло много популярных двумерных игр:
Battletoads – продолжение серии игр в жанре beat ’em up, файтинг;
Spiritfarer – игра в жанре «ферма», менеджмент;
Carrion – игра в жанре «ужасы», метроидвания;
Creaks – игра в жанре «квест», головоломка;
Streets of Rage 4 – игра в жанре beat ’em up, файтинг.
Программная реализация 2D-игр проще не только из-за отсутствия третьего измерения: на самой сцене меньше объектов, вместо трехмерных моделей плоские спрайты, вместо скелетной анимации – покадровая. А еще 2D-игры проще портировать на другие платформы – легче найти новую аудиторию.
Особенности создания 2D-игр на Unity
Давайте создадим простую игру в жанре пинг-понг ?. Перед тем как приступить к созданию игры, продумайте, какой именно результат хотите получить. На первых этапах рекомендуется использовать схематические шаблоны, чтобы быстрее получить работающий результат. В этой инструкции мы так и поступим. Графических ресурсов использовать не будем: и ракетки, и отбиваемый мяч будем пока отображать простыми белыми спрайтами.
Предварительно рассмотрим основные понятия Unity, без понимания которых будет проблематично создать игру:
Ресурс или Asset – основной строительный блок для любого проекта Unity. Это может быть изображение, трехмерная модель, звук. Чтобы не путать с префабами или игровыми объектами, рекомендуется размещать ресурсы в отдельной папке Assets.
Игровой Объект или GameObject . Если ресурс используется в сцене, то он становится игровым объектом. Например, у нас есть изображение противника – это ресурс. Когда же мы создадим на сцене 20 противников, то получим 20 игровых объектов.
Компоненты влияют на поведение и отображение игровых объектов.
Префаб – способ хранения игровых объектов, оптимизированный для многократного использования и клонирования с разными настройками. При изменении префаба изменяются все его копии.
Скрипт – исходный текст программы на языке C#. Могут прикрепляться к игровым объектам или префабам.
Пошаговый процесс создания 2D-игры на Unity
Предполагаем, что вы уже установили редактор и создали аккаунт на портале Unity.
В первую очередь создадим новый проект и откроем его настройки (Edit → Project Settings). Во вкладке Editor установим параметр Default Behaviour Mode в значение 2D
Настройка проекта
Детальная настройка проекта
Следующим шагом сохраним текущую активную сцену, назвав ее, например, Scene1. Теперь создадим основные игровые объекты: ракетку, мяч и менеджер игры, в котором будет храниться основная логика игры.
1. Создаем пустой объект, переименовываем в GameManager.
Создаем пустой объект
2. Создаем C#-скрипт с названием GameManager. Ассоциируем скрипт с объектом GameManager, перетащив мышкой скрипт на объект.
Создаем C# скрипт
3. Создаем квадратный спрайт, называем его Pad (Assets → Create → Sprites → Square). Аналогично создаем круглый спрайт Ball (Assets → Create → Sprites → Circle). Масштабируем спрайт Pad со следующими параметрами – x:0.5, y:2.5, z:1.
Создаем спрайты
4. Создаем префабы для Pad и Ball, после чего добавляем к ним компонент Box Collider 2D (включаем параметр Is Trigger) и компонент Rigidbody 2D (выставляем параметр Body Type в значение Kinematic).
Добавляем .компонент Box Collider 2D
Настраиваем.компонент Box Collider 2D
Добавляем компонент Rigidbody 2D
Масштабируем спрайты
5. Создаем C#-скрипты Ball и Pad. Ассоциируем их с префабами.
6. Заполняем скрипты следующим кодом.
GameManager.cs
using System.Collections; using System.Collections.Generic; using System.Security.Cryptography; using UnityEngine; public class GameManager : MonoBehaviour { // Публичная переменная для ракетки, будет ассоциироваться с префабом Pad public Pad pad; // Публичная переменная для ракетки, будет ассоциироваться с префабом Pad public Ball ball; // Публичная переменная со значением нижнего левого угла экрана public static Vector2 bottomLeft; // Публичная переменная со значением верхнего правого угла экрана public static Vector2 topRight; void Start() { // получаем значение нижнего левого угла экрана bottomLeft = Camera.main.ScreenToWorldPoint(new Vector2(0,0)); // получаем значение верхнего правого угла topRight = Camera.main.ScreenToWorldPoint(new Vector2(Screen.width, Screen.height)); // создаем мяч Instantiate(ball); // создаем две ракетки Pad padVar1 = Instantiate (pad) as Pad; Pad padVar2 = Instantiate (pad) as Pad; padVar1.Init (true); // Инициализируем левую ракетку padVar2.Init (false); // Инициализируем правую ракетку } }
Ball.cs
using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Threading; using UnityEngine; public class Ball: MonoBehaviour { [SerializeField] float speed; float radius; Vector2 direction; void Start() { direction = Vector2.one.normalized; radius = transform.localScale.x / 2; } void Update() { // Обрабатываем движение мяча transform.Translate(direction * speed * Time.deltaTime); // Обрабатываем столкновения с краями экрана if(transform.position.y < GameManager.bottomLeft.y + radius && direction.y < 0) { direction.y = -direction.y; } if (transform.position.y > GameManager.topRight.y - radius && direction.y > 0) { direction.y = -direction.y; } // Обрабатываем выигрыш игрока if (transform.position.x < GameManager.bottomLeft.x + radius && direction.x < 0) { UnityEngine.Debug.Log("Right win"); } if (transform.position.x > GameManager.topRight.x - radius && direction.x > 0) { UnityEngine.Debug.Log("Left win"); } } // Обрабатываем столкновение ракетки и мяча void OnTriggerEnter2D(Collider2D other) { if(other.tag == "Pad") { bool isRight = other.GetComponent<Pad>().isRightPad; if (isRight == true && direction.x > 0) { direction.x = -direction.x; } if (isRight == false && direction.x < 0) { direction.x = -direction.x; } } } }
Pad.cs
using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Security.Cryptography; using System.Threading; using UnityEngine; public class Pad : MonoBehaviour { [SerializeField] float speed; float height; string inpt; public bool isRightPad; // Вызывается в начале игры, перед первым обновлением кадра void Start() { height = transform.localScale.y; } public void Init(bool isRight) { isRightPad = isRight; Vector2 pos = Vector2.zero; // Обрабатываем изменение позиции ракетки. Для левой и правой ракетки - отдельно. if (isRight) { pos = new Vector2(GameManager.topRight.x, 0); pos -= Vector2.right * transform.localScale.x; inpt = "PadRight"; } else { pos = new Vector2(GameManager.bottomLeft.x, 0); pos += Vector2.right * transform.localScale.x; inpt = "PadLeft"; } transform.position = pos; transform.name = inpt; } void Update() { // Блокируем выход ракетки за края экрана, обрабатываем изменение позиции на экране float move = UnityEngine.Input.GetAxis(inpt) * Time.deltaTime * speed; if(transform.position.y < GameManager.bottomLeft.y + height/2 && move < 0) { move = 0; } if (transform.position.y > GameManager.topRight.y - height / 2 && move > 0) { move = 0; } transform.Translate(move * Vector2.up); } }
6. Добавляем к префабу Ball и Pad теги с аналогичными именами. Выделив префабы, в инспекторе мы можем видеть выпадающий список тегов. Там же расположены и кнопки для добавления и редактирования тегов.
7. В настройках камеры выставляем параметр Projection в значение Orthographic, а параметр Clear Flag – в значение Solid Color.
Настройка камеры
8. Настраиваем кнопки, как показано на следующих скриншотах (Edit → Project Settings → Input Manager).
Настройка ввода, основное
Настройка ввода, первый игрок
Настройка ввода, второй игрок
Вот и всё, игра готова!
Пинг-понг, итоговый результат
Билд для платформы Windows
Исходный код
Дополнительные туториалы
1. Официальный туториал от Unity, где детально рассмотрен процесс создания roguelike RPG.
2. Youtube-канал Brackeys, где можно найти серию видеоуроков по созданию 2D-платформера.
3. Youtube-канал N3K EN содержит множество уроков как по отдельным компонентам Unity, так и полноценные серии уроков по созданию игр с нуля.
***
Если у вас мало опыта в разработке игр на Unity, мы рекомендуем обратить внимание на факультет разработки игр GeekBrains. Материал хорошо структурирован и содержит все необходимое для того, чтобы стать профессиональным Unity-разработчиком.
В числе прочего вы разработаете 2D-платформер с физическими загадками и динамическим освещением, научитесь портировать его на мобильные устройства. Кроме того, разработаете полноценную браузерную стратегию, а также игру в жанре двухмерных гонок.
По окончании обучения вы будете иметь портфолио из 4 игр, которое можно показать на собеседовании. Если же какая-то часть материала будет непонятна, вы всегда можете обратиться к персональному преподавателю.
? Интересно, хочу попробовать!