Как сделать пол в юнити 2д

Добавил пользователь Cypher
Обновлено: 05.10.2024

Создание 2D змейки в Unity.

Пример создания простой 2D игры змейка (так же известной как snake, slither) в среде Unity.

Дл начала создадим проект 2D. На сцене разместим три спрайта и подпишем Head, BodyPart, FoodItem.

Head - это наша голова, которой мы и будем управлять.
BodyPart - часть тела, которая будет добавляться по мере съедания Food. Так же с добавлением длинны тела, будем менять и скорость.

Если вышли за пределы экрана, респавним в начальной точке и отсекаем часть туловища.

Управление змейкой.

Создадим скрипт SnakeController. Добавим свойство

Массив parts будет содержать наше тело, включая голову. Текущий угол поворота будет в переменной currentRotation. В bodyPart будет префаб с частью туловища. speed и speedRotation будет отвечать за скорость перемещения и поворота соответственно.

В функции Start добавим себя (голову) в массив частей тела.

В функции Update напишем

То есть мы получаем от -1 до +1 значение поворота и умножаем его на время, прошедшее с прошлого обновления и на коэффициент скорости вращения. Для инверсии отнимаем от текущего угла.

Далее используем вспомогательную функцию Quaternion.Euler которая возвращает поворот на заданный угол вокруг каждой из осей. Так как нас интересует только вращения вокруг оси Z, X и Y можно передать 0.

И вызываем Translate для перемещения головы вперед с заданной скоростью с учетом угла поворота указанного выше.

Для управления головой этого уже достаточно.

Создадим еще один скрипт BodyPart.

В свойстве parentObject будет объект за которым будет следовать данная часть тела змейки.

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

То есть движется голова, за ней первый объект BodyPart. Он поворачивается в сторону головы и сдвигается. Если третий параметр 1.0f будет возвращен второй параметр функции Lerp, то есть наш объект переместится в точку где находится голова. Если же передать 0.0f, будет возвращена позиция текущего объекта и он останется на месте.

Таким коэффициент 3.0f немного сожмет части тела змейки чтобы они не были слишком далеко. Умножение на скорость, даст еще большее прижатие с увеличением скорости. То есть чем больше частей, тем больше скорость, тем компактнее они будут.

Еда для змейки

Добавим одноименный тег на объект FoodItem для определения еды. Добавим на объекты Head и BodyPart по Circle Collider 2D. Это нужно для определения пересечения головы и еды. При пересечении коллайдеров будет вызвана функция OnTriggerEnter2D. Но для этого необходимо еще повесить на объект Head компонент Rigidbody 2D. Без него триггер не сработает.

Rigidbody по умолчанию имеет массу и гравитацию, и будет падать вниз экрана, поэтому уберем гравитацию (Gravity Scale) в 0.

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

Достаем из нашего массива частей тела предыдущую часть, за которой будет следовать новая. И спавним BodyPart в месте где сейчас голова. Задаем нашей новой части тела объект за которым следовать. Так же передадим контроллер головы, для доступа к скорости (цель использования скорости описаны выше). Помещаем наш объект в массив частей тела змеи. И увеличиваем скорость движения змеи для большей сложности.

Добавим скрипт SnakeController на объект Head, а скрипт BodyPart на одноименный объект. Перетянем BodyPart в папку Assets тем самым создав префаб.

На объекте Head в скрипте в свойстве Body Part выберем созданный только что префаб.

Генератор еды для змейки

Создадим префаб FoodItem. В нем можно прописать вес еды и присвоение картинки. В репозитории вы найдете скрипт с заданием случайного спрайта нашему FoodItem.

Создадим скрипт FoodManager .

Свойство foodItem ссылается на префаб FoodItem.

Функция Add добавляет на экран в случайных координатах один объект еды. При старте создаем 7 объектов еды.

Добавим в SnakeController при съедании одного объекта, создание нового в случайном месте.

Объявим новое свойство

В методе Start присвоим ему наш скрипт. Можно повесить сразу на Head скрипт FoodManager. Но я создал пустой объект на сцене, повесил на него скрипт, и задал имя FooManager. Если змеек будет не одна, то два менеджера еды не нужны :)

В функцию Start добавим

В функцию OnTriggerEnter2D после изменения скорости

На этом пожалуй я закончу.

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

В нем есть проверка выхода за пределы экрана и сброс половины веса а так же спрайты.

Хабралюди проявили некоторый интерес к Unity, поэтому открываю этим постом цикл туториалов, освещающих основные моменты работы с объектом (цикл неопределённой пока длительности — если кому окажется полезным продолжу).

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

Let’s get it started

Предстартовая подготовка

Для начала качаем и устанваливаем собственно сам Unity на офсайте, выбрав лицензию с ценником Free. Можно скачать и тридцатидневный триал UnityPro, это на ваш вкус.

При первом запуске перед вами предстанет окошко Project Wizard’а (у вас там будет пусто):

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

f3437cc4

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

Иерархия объектов на сцене — это список всех объектов на текущем уровне, показывающий заодно отношения Parent-Child.

Инспектор объектов показывает компоненты и их свойства выделенного в данный момент объекта — модели, текстуры, префаба.

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

В главном окне редактирования мы пользуемся всеми прелестями драг’н’дропа для расставления объектов по уровням.

Для начала посмотрим, что у нас уже есть в дефолтной сцене. Негусто, правда? Объект с говорящим названием Main Camera, по нажатию на название которого в иерарахии мы увидим конус viewport’а и маленькое окошко с видом из камеры.

Земля обетованная

Но возвращаясь к нашим баранам, создадим поверхность, по которой будем ходить. Моделей у нас нет пока, поэтому можно создать просто большую плоскость… Но мы создадим землю, то бишь Terrain — он покрасивше голой плоскости будет. Для этого в меню выбираем Terrain->Create Terrain. Вуаля!

ff9ea52c

Опять-таки, не очень впечатляет. Для начала, сменим размер земной тверди через Terrain->Set Resolution. По умолчанию параметры Length и Width равны 2000, т.е. 2 км на 2 км. Для тестовых побегушек нам столько не надо, потому пишем в эти поля 500 и 500 — более чем достаточно.

a8c2e9ca

Выбираем нужную текстуру, например Grass(Hill). Можно добавить ещё несколько текстур, например Cliff (Layered Rock), и, пользуясь кистью, выбираемой чуть выше, раскрасить по своему усмотрению. У меня после предыдущих манипуляций получилось вот так:

3378d4d5

6a1c76e8

Управление и камера

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

Вообще-то, в комплект Юнити входят два игровых объекта, дающих готовое, уже собранное решение для камеры и управления. Но я о них вам пока не скажу, чтобы был стимул собрать своими руками. 🙂

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

0dd7ed3c

Любой предмет, который мы видим на сцене — это экземпляр класса с говорящим названием GameObject. Он имеет некоторое количество т.н. компонентов — в свою очередь, являющихся экземплярами своих классов. Каждый компонент выполняет некую утилитарную функцию. Так, у каждого GameObject должен быть компонент Transform, который занимается тем, что хранит текущие координаты, угол разворота и размеры объекта в трехмерном пространстве. Ну и заодно содержит методы для выполнения действий над положением объекта в этом пространстве: пермещение, развороты и т.д., т.е. когда мы в редакторе тянем объект за стрелки-управляторы, мы меняем координаты его трансформа.

А вот например компонент RigidBody занимается тем, что обрабатывает физическое поведение объекта: всё, что мы видим, когда бочка от выстрела падает на бок и катится — результат работы RigidBody. Который, кстати, не сможет правильно работать, если не назначить объекту компонент типа Collider, который хранит в себе трехмерную модель, по которой определяются столкновения объекта. Эта модель не отображается, но именно она, а не та что мы видим на экране во время игры, проверяется на столкновения с окружающим миром.

Но мы всё еще стоим на месте: ведь у нас нет скрипта, который перехватывал нажатия клавиш и сообщал о них в CharacterMotor. Этим занимается лежащий в той же папке скрипт FPSInputController. Кидаем его на игрока, запускаем и ура — кнопки W, S, A, D теперь позволяют ходить, а пробел — прыгать! Но ходим-то мы всё как-то в одну сторону, вправо-влево да приставным шагом. Чтобы вертеть головой и идти куда глаза глядят, понадобится ещё один скрипт, оттуда же: MouseLook. Кидаем, запускаем — и получаем полноценное управление.

Теперь можно поиграться с переменными. Character Cоntroller установил вместе с собой Character Motor — в его-то свойствах и хранятся такие параметры, как Gravity, Max Forward Speed, Jumping Base Height и всякие другие. Вот они, все плюсы Инспектора — все основные свойства классов всегда на виду, даже в код лезть не надо.

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

Стрельба по изредка движущимся мишеням

Бегать по собственноручно сделанным холмам, любовно раскрашенным аж тремя текстурами, конечно, весело. Но вскоре надоедает. Поэтому мы выберем в меню GameObject->Create other->Cube, разместим этот куб в воздухе рядом с игроком, в свойствах Transform у него укажем следующие параметры Scale (x, y, z): 3, 3, 3; и запустим уровень, чтобы посмотреть, что этот куб будет делать. Делать он не будет ровным счетом ничего, если честно. Но стоит, выделив этот куб, назначить ему, Component->Physics->Rigidbody, при следующем запуске мы увидим совсем другую картину. Куб падает, крутится, почти как настоящий, правда как картонный — масса его по умолчанию 1 кг, что для таких размеров маловато, но мы её пока трогать не будем.

Выделив куб, нажмём Ctrl+D (дублирование объекта), и с зажатым Ctrl потянем куб вверх до тех пор, пока кубы не будут расположены один над другим. Теперь у нас два совершенно одинаковых куба ровно друг над другом. Повторим эту процедуру кубов до 15, и посмотрим на падение Вавилонской башни.

Далее, создаем новый куб, но не назначаем ему Rigidbody. Из него мы сделаем ровную поверхность для удобства стрельбы. Задаем ему Scale: 150, 20, 150; и располагаем где угодно — главное разместить на нем нашу башню и игрока. У меня получилось так:

88d5d64b

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

public var bulletImpulse = 300;
public var shootSpeed = 1;
public var bullet : GameObject;

public var lastShotTime : float;

if (Input.GetKey(KeyCode.Mouse0)) (lastShotTime + shootSpeed)) Material.

Назовем его bulb и положим в папку Materials.

Выберем buld и перенесем нашу текстуру из Project View на пустой серый квадрат в Inspector View (с надписью none(Texture 2D)), либо нажав на Select все в том же квадрате и выбрав ее из появившегося списка.

Взамен серого квадрата появится иконка с текстурой.
Перетяним наш материал на куб. Куб сразу станет текстурированным.

При выборе материала в Inspector View вы так же можете выбрать шейдер, по которому будет расчитываться его конечный вид

PS: О шейдерах мы обязательно поговорим отдельно, но много позже.

Так же у материала можно настраивать tiling (мозаичное размещение текстуры). Чем больше значения tiling по x-ой или y-ой координате, тем больше раз она повторяется по соответствующей стороне. Чтобы понять как это работает — поставте значения по x и y равным 10 (при изменении значения текстура на кубе будет обновляться в реалтайме).

Базовый Урок 10 — Основы работы с аудио

В уроке рассказывается, как проигрывать компонент Audio Source (аудио ресурс) и вызывать звуковые клипы с помощью скриптинга.

Обычно AudioListener является компонентом у камеры. Выберем камеру и убедимся в этом, посмотрев в Inspector View.

Для того чтобы слушать звуки вы должны иметь хотя бы один AudioListener в каждой сцене.

Добавим пустой GameObject и добавим к нему компонент Audio Source.

Добавить аудио-клип можно либо через Inspector View, либо с помощью скрипта.

В нашем проекте есть два аудио-файла — моно и стерео.

Моно обычно используется для звуковых эффектов. Только для него можно использовать затухание или другие 3d-эффекты.
Стерео, соответственно, для музыки, т.к. стереозвук прогирывается как есть.

В окне Preview можно проиграть выбранный файл.

Добавим наш клип (GreenadeLaunch) в поле Audio Clip. Если включен параметр Play On Awake, то звук будет проигрываться сразу после запуска сцены.

Добавим скрипт к пустому GameObject, а значение переменной myClip у скрипта проиницилизируем звуковым файлом (GreenadeLaunch). Теперь нажав на play вы снова усшылите звук.

Проигрывать аудио можно и без использования Audio Source. Удалим компонент Audio Source c нашего GameObject, а код в теле метода Start() заменим следующим:

Тут, PlayClipAtPoint — статическая функция класса AudioSource, которая создает новый GameObject, с соответствующим Audio Source (в нашем случае это myClip) и после проигрывания аудио-клипа удаляет данный GameObject.

Сохраните скрипт и убедитесь что он есть у нашего GameObject, а значение myClip равно GreenadeLaunch.

Жмем Play и сразу после загрузки сцены жмем на Pause чтобы убедиться что на сцене появился новый игровой объект с именем One Shot Audio.

Базовый Урок 11 — Основы соединений

Чтобы связать сферу и цилиндр — выбирете сферу (Ball) и добавьте к ней компонент Fixed Joint. Переменную Connected Body проинициализируем значением Cylinder.rigidbody. Напомню, что для этого достаточно перетащить Cylinder из Hierarchy view в Inspector View, на поле напротив Connected Body.

Переименуем Cylinder на более подходящее названия для крепежа шара, например, Ballstem. Значение переменной Connected Body поменяется автоматический.

Нажмите play и увидите как шар падает вместе с прикрепленным к нему цилиндром.

Теперь начнем создавать подвижные участки цепи.
Создадим капсулу (назовем ее Chain1), при этом размеры ее будут аналогичны размерам Ballstem’а, а находится она будет чуть выше него, чтоб крайние грани объектов пересекались. Chain1 так же будет с компонентом rigidbody.

А к Ballstem’у добавим компонент Hinge Joint, у которого
Connected Body мы инициализируем Chain1.rigidbody.
Место закрепление обозначенно ораньжевой стрелкой.

Нам потребуется еще один участок цепи. Выберем Chain1 и сделаем его дубликат (ctrl+D или cmd + D). Переименуем его в Chain2, так же сдвинув его к верхушке Chain1. К Сhain1 добавим Hinge Joint, с
Connected Body равным Chain2.rigidbody.

Аналогично добавим Chain3.

Выделем Ball, Ballstem, Chain1, Chain2, Chain3 и наклоним их.

Жмем play и смотрим как перемещаются наш шар с цепью.

Базовый Урок 12 — Ввод с использованием виртуальных осей

На это раз на сцене у нас есть плоскость (floor), камера (Main Camera), источник света (Point light) и пустой gameObject.

Посмотрим на некоторые дефолтные параметры:

ПараметрЗначениеКомментарий
Negative ButtonleftКлавиша для перемещения в отрицательном направлении
Positive ButtonrightКлавиша для перемещения в положительном направлении
Alt Negative ButtonaАльтернативная клавиша для перемещения в отрицательном направлении
Alt Possitive ButtondАльтернативная клавиша для перемещения в положительном направлении
TypeKey or Mouse ButtonТип ввода, для перемещения вдоль данной оси (в нашем случае X)
AxisX axisОсь объекта, вдоль которой мы будем перемещаться

Для того, чтобы использовать данное перемещение (Horizontal), нам потребуется метод GetAxis() класса Input.

Добавим скрипт к пустому gameObject’у, и нажмем play. Если зажать стрелку влево/вправо (или же a/d), в status bar’е вы увидите как меняется значение переменной horiz:

Добавим еще строчку кода в Update(), сразу за Debug.Log():

Запустим сцену и нажмем на стрелку — вы увидите, как наш gameObject начнет перемещаться вдоль оси X.

Physics Material 2D используется для настройки трений и отскакиваний, которые происходят между 2D физическими объектами при их столкновении. Создать 2D физический материал можно через меню Assets ( Assets > Create > Physics Material 2D ).


Свойства

Свойство: Функция:
Friction Коэффициент трения для данного коллайдера.
Bounciness Степень отскока столкновений от поверхности. Значение 1 означает что нет отскока, в то время как значение равное 1 означает хорошую отскакиваемость без дальнейшей потери энергии.

Детали

Для использования 2D физического материала, просто перетащите его на объект к которому привязан 2D коллайдер и перетащите его на компонент коллайдера в инспекторе. Заметьте, что для 3D физики эквивалентный ассет упоминается как Physic Material (т.е. без S в слове physic) - для скриптинга важно, чтобы не возникал конфликт между двумя командами.

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

Джоинты

2D джоинты представляют собой обычные физические объекты, которым можно придавать силу, перемещать, бросать сталкивать и тд, в общем – делать все то, что мы обычно делаем с физическими объектами в Unity . Особенность же джоинтов в том, что с их помощью можно создавать связи с другими физическими объектами на сцене. В этом случае все действия, которые мы совершаем над одним объектом, будут также влиять на другие – связанные с ним объекты.

Все компоненты джоинтов можно найти во вкладке Component -> Physics 2D .

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

Как это работает

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


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

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

Начнем с поля Connected Rigid Body . В это поле можно поместить любой физический объект с которым необходимо установить связь.


Далее поле Enable Collision , которое включает и отключает коллизии между джоинтом и присоединенным объектом.


Поле Anchor , представляет собой Vector2, в котором можно указать место расположения крепления джоинта относительно его Transform’а . Обычно место расположения джоинта указывают сразу при создании на сцене и поле Anchor оставляют без изменений.


Следующее поле Connected Anchor, также представляет собой Vector2 , где уже в свою очередь необходимо указать конкретно точку крепления объекта к джоинту относительно самого Transform’а джоинта.


По умолчанию поле Auto Configure Connected Anchor включено и поэтому точка крепления объекта к джоинту указывается автоматически как “ центр ” самого объекта. К примеру, когда нужно “ зацепить ” объект за какой либо край, галочку напротив поля Auto Configure Connected Anchor необходимо снять и вручную установить “ место зацепления ”.


Поле Break Force указывает силу, при превышении которой произойдет разрыв соединения между джоинтом и объектом. По умолчанию стоит значение Infinity , при котором разрыва соединения не произойдет.


У большинства джоинтов также имеется поле Break Torque , где можно указать силу, при которой произойдет разрыв соединения при вращении. Также как и поле Break Force – по умолчанию имеет значение Infinity .

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

Fixed joint

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

У этого джоинта помимо стандартных настроек Break Force и Break Torque есть новые поля Damping Ratio и Frequence , изменяя которые можно определить, как сильно объект фиксируется в точке. Оба поля принимают числовое значение, где 0 означает полную фиксацию объекта, вне зависимости от внешних воздействий на объект.


Hinge joint

Следующий Hinge joint , также фиксирует объект в точке, и в отличие от Fixed joint не прерывает “ воздействия ” физики на сам объект.

Этот джоинт позволяет применять силу для совершения вращения объекта, а также вводить ограничения на угол вращения. Для этого в компоненте есть поле Motor , где указаны две переменные – Motor Speed и Maximum Motor Force , для скорости вращения и максимальной силы, применяемой для совершения вращения. Ограничивать угол вращения можно в поле Angle Limits , где для этого введены две переменные – Lower и Upper Angle – нижнего и верхнего предела угла вращения.

Slider joint

Этот джоинт немного похож на предыдущий Hinge joint , он тоже позволяет применять силу к объекту. Разница в том, что Hinge joint это делает для вращения объекта, а Slider joint применяет эту силу, чтобы двигать объект под определенным углом.

Также этот джоинт имеет новое поле Angle, где можно указать под каким углом объект будет перемещаться.


Distance joint

Следующий джоинт, как и остальные, имеет стандартный набор настроек, а также новое поле Distance, где можно указать минимальное расстояние между джоинтом и объектом. Если собрать “ цепь ” из нескольких таких джоинтов, то можно получить отличный аналог веревки, которая не растягивается и не рвется.

Spring joint

Этот джоинт также имеет поле Distance , но в отличие от Distance joint – позволяет имитировать “ пружину ” при растягивании. Как и Fixed joint – имеет поля Damping Ratio и Frequency , где можно указать – как быстро и сильно необходимо фиксировать объект к джоинту.

Target joint

Особый джоинт из всего списка, которому нельзя указать объект для присоединения – у него просто нет такого поля. Дело в том что если раньше мы сначала определяли позицию джоинта на сцене и к нему уже крепили объект, то в случае с Target joint – сам объект и является джоинтом, и вместо крепления к другому джоинту, он крепится к определенной точке на сцене. Для этого у него есть новое поле – Target, представленное в виде Vector2 , где можно указать локальную точку крепления относительно объекта.

По принципу работу он немного похож на Spring joint, в котором также есть поля Damping Ratio и Frequency.

Заключение

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

2D Тайлмап. Работа с контентом: от изображения к уровню

В Unity 2017.2 к возможностям работы с 2D добавили Тайлмапы (Tilemap). Используя карты тайлов, ты можешь быстро компоновать и создавать 2D-уровни с помощью комбинации спрайтов и контролировать такие свойства, как порядок слоёв, тайлмапные коллайдеры, анимированные тайлы и многое другое! В этой записи я постараюсь рассказать о всём рабочем процессе, начиная с импорта файлов изображений в Unity и до создания уровня для 2D-платформера!

Коротко процесс работы можно описать так:

Sprite -> Tile -> Palette -> Brush -> Tilemap

Для новичка эти термины Unity могут показаться немного запутанными. Но мы представим это как рисование на настоящем холсте:

Тюбик с краской -> Краска -> Палитра-> Кисть -> Холст

К концу мы соберём уровень из этих кусочков так, что 2D-персонаж сможет бегать по уровню.

1) Спрайты (Sprites)

Импортировать изображения в Unity можно разными способами:

После того как мы импортировали изображение в проект, его тип текстуры (Texture Type) определяется в зависимости от режима твоего проекта 2D или 3D.

Создание 2D проекта в Unity

Настройка проекта в Unity

Тип текстур в Unity

Режим спрайта Single или Multiplee

Окно редактора спрайтов позволяет нарезать изображение на несколько спрайтов; так что ты сможешь сделать одно изображение со множеством рисунков (spritesheet) в любом программном обеспечении для редактирования изображений и определить, какие области изображения рассматриваются как отдельные спрайты прямо в Unity. Не надо плодить и управляться с сотнями отдельных файлов изображения!

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


Тайлы (плитки) в Unity

В Unity 2017.2 появилось новое окно: палитра плиток (Tile Palette). Это окно является неотъемлемой частью использования тайлмап-системы, организуя интерфейс для выбора плиток (Tiles).

Палитра плиток (тайлов)

Палитра тайлов

Чтобы не таскать по одному изображению, есть вариант перетащить лист спрайтов (Spritesheet), который содержит нарезанные спрайты, чтобы автоматически создать набор плиток (Tiles) на палитре.

4) Grid & Tilemap

Для начала нам нужно создать новый тайлмап на нашей текущей сцене; это можно сделать в выпадающем меню: GameObject -> 2D Objects -> Tilemap. Это не только создаст тайлмап, также создаётся игровой объект сетка (Grid), для которой новый тайлмап автоматически станет дочерним.

Сетка для тайлов в Unity

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

5) Рисование на тайлмапе!

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

Выбор карт тайлов

На скриншоте сложная сцена со множеством тайлмапов

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

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

Настройка пикселей на юнит в Unity

6) Тайлмап коллайдер (Tilemap Collider) и составной коллайдер (Composite Collider)

Сейчас у тебя есть все знания, чтобы нарисовать готовый уровень.

Тайлмап коллайдер в Unity

Когда ты добавишь персонажа с физикой и войдёшь в режим игры, он провалится сквозь землю. Вместе с тайлмап-системой появился очень полезный 2D-компонент тайлмап коллайдер (Tilemap Collider). При применении к тайлмапу, он будет автоматически создавать коллайдер вокруг плиток. Тогда в режиме игры, наш персонаж сможет бегать и прыгать на тайлмапе!

Если ты решишь изменить планировку уровня (например, добавить больше плиток или удалить некоторые), то тайлмап коллайдер автоматически обновится!

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

Еще один полезный компонент, который добавили в 2D набор физики — составной коллайдер (Composite Collider). Добавление его к тайлмап коллайдеру объединит все коллайдеры плитки в более оптимальную геометрию сетки коллайдера.

Если после этой подробной статьи у тебя остались вопросы, оставляй комментарий ниже, обсудим!

Читайте также: