Unity Bolt: #2. Платформер — движение, анимация, рейкасты

В прошлой статье было небольшое введение в принцип работы Bolt и основы визуального программирования. В этой же попробуем небольшой платформер сделать и затронем основные аспекты.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Цикл статей

  • Введение
  • Платформер — движение, анимация, рейкасты

Оглавление

Туториалы можно скачать бесплатно с Гитхаба. Каждый туториал будет отдельной папкой в проекте. Конкретно этот туториал будет лежать в директории Assets/Tutorials/02 — Platformer. Буду благодарен лайкам репозиторию.

Подготовка

Накидаем простенькую сцену с платформами и шипами. Я использовал редактор Тайлов, но это могут быть и обычные спрайты с колайдерами на них. Добавляем в иерархию GameObject игрока.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

В инспекторе добавляем к объекту компонент Flow Machine.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Нажимаем Edit Graph и приступает к настройке графа.

Движение персонажа

Мы хотим, чтобы персонаж двигался влево и вправо в зависимости от горизонтальной оси ввода, для которой предварительно настроены сочетания клавиш A и D на клавиатуре или левый джойстик на контроллере. Когда вы идёте влево, возвращается -1, а когда вправо, то +1. Скорость движения зададим в переменной.

Для начала можно зайти в настройки и задать необходимое управление в Edit > Project Settings > Input Manager, если не нравятся дефолтные настройки.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Теперь добавим переменную, откуда будем читать скорость. В инспектора объекта игрока добавим переменную в компоненте Veriables. Подробнее можно почитать в документации.

Далее, собственно, нам нужно получить горизонтальную ось ввода. Мы можем сделать это с помощью блока Get Axis.

  • Добавляем узел Codebase > Unity Engine > Input > Get Axis.
  • Вводим «Horizontal» (зарезервированное слово).

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

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

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

  • От выхода узла GetAxis тащим указатель и создаём узел Multiply.
  • От второго входа нового узла тянем указатель и создаём узел для чтения переменной Variables > Object > Get Object Variable.
  • Выбираем там Speed.
  • Выход узла Multiply соединяем с новым узлом Variables > Graph -> Set Graph Variable.
  • Дадим новой переменной имя Movement.
  • Соединяем управляющий вход с Update.

Каждый кадр (событие Update) мы получаем значение инпута по оси X в диапозоне [-1;1], домножаем на скорость и сохраняем в переменную Movement.

Теперь нужно задать компоненту Rigidbody 2D персонажа скорость. Скорость состоит из двух составляющих — по осям X и Y, которые пакуются в Vector2.

  • Добавляем узел Get Variable для получения Movement из предыдущего шага.
  • Это передаёт на вход X координате новой ноде Vector2.
  • А в Y передаём считанную Y координату из текущей скорости (Codebase > Unity Engine > Rigidbody 2D -> Get Velocity).
  • Полученный вектор передаём на вход узлу для установки нового значения скорости (Codebase > Unity Engine > Rigidbody 2D -> Set Velocity).

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

Ну и заодно сгруппируем узлы. Это делается выделением с зажатой клавишей Ctrl.

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

Даже при движении влево спрайт всё равно смотрит вправо. Хорошо бы это исправить. Для этого будет инвертировать значение скейла по оси X.

  • Если двигаемся вправо (значение Movement больше 0), значение Scale должно быть положительным.
  • Если движемся влево (значение Movement меньше 0), значение Scale должно быть отрицательным.
  • Если стоим на месте (значение Movement равно 0), то ничего не делаем.

Значение Y и Z оставляем как есть.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Если запустить редактор, то увидим, что спрайт персонажа отзеркаливается в зависимости от направления движения.

Но сейчас персонаж просто скользит. Хотелось бы сделать анимацию движения.

Анимация

Возьмём готовые спрайты и анимации из примера проекта Penny Pixel.

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

Ну и флажок grounded пока в true выставим, чтобы не запускалась анимация полёта.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

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

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Остаётся только соединить с остальным графом и запустить.

Следующим шагом добавим возможность прыгать.

Придание силы объекту для прыжка

  • Добавим глобальную переменную для силы прыжка и назовём JumpPower.
  • Events > Input, а там On Button Input.
  • Вместе со считанной силой прыжка передаём в Codebase > Unity Engine > Rigidbody 2D > Add Force (Force, Mode).
Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Если запустить, то по нажатию на Space персонаж будет прыгать. Но есть одна проблема…

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

Создадим новый слой и назначим его платформам.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

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

Переиспользование логики

Так как эта проверку нужна в двух местах, то выделим всю логику в отдельный юнит Assets > Create > Bolt > Flow Macro.

Для каста использовать будем CircleCast. Хотя это не так принципиально.

  • Получаем позицию текущую.
  • Делаем рейкаст по слою Platform, направляя вниз с радиусом 2 и дальностью 2.
  • Результат получаем в отдельную ноду.
  • Делаем проверку на то, было ли столкновение.
  • Результат проверки столкновения луча с платформой пишем в bool переменную IsGrounded на выход.
Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Теперь в графе персонажа нужно немного изменить узлы, обрабатывающие прыжок.

  • Перетаскиваем на граф персонажа граф GroundCheck.
  • Добавляем ветвление.
  • Соединяем с узлом, задающим силу.

Если запустить, то увидим, что персонаж теперь может прыгать только находясь на платформе.

Точно также добавим проверку к анимации.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

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

Хотелось бы как-то визуализировать дебажную информацию для отладки.

Отладка и OnDrawGizmos

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

В нашем случае просто будет рисовать линию. Увеличим дальность луча до 50 и добавим соответствующие узлы для отрисовки линии.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты
  • Вытаскиваем информацию о текущем положении.
  • Создаём Vecto3 на основе X и Z координаты. Эта позиция будет конечной при отрисовки линии.
  • Рейкаст мы делаем вниз, поэтому в Y координату вписываем Y координату текущего положения персонажа с за вычетом дальности луча.
  • Добавляем ивент, который каждый кадр рисует информацию.
  • На вход узла по отрисовке в начальную координату передаём текущее положение персонажа, а конечной точкой будет новое вычисленное значение позиции.

Ещё нужно в Scene View включить отображение Gizmos.

Unity Bolt: #2. Платформер — движение, анимация, рейкасты

Теперь запустим и посмотрим.

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

В следующей статье поработаем с окнами и сделаем экран смерти персонажа с перезапуском сцены.

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

139139
113 комментария

Я бы еще добавил сюда что-нибудь про слоупы. Диагонали очень неприятная тема для начинающих, но с ними рано или поздно придется столкнутся (pun intended).

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

Еще с рейкастами можно делать вот такие штуки:       

27

Но есть одна проблема…находясь в воздухе, снова нажать Space, то персонаж прыгнет ещё разЗолотой стандарт туториалов по платформерам соблюден, лайк.

16

Комментарий недоступен

7

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

3

Как по мне для взрослого человека особо не будет никакой разницы по сложности: прочитать туториал по нодам, или ознакомится с несколькими строками кода Категорически поддерживаю. C# или какие-нибудь проприетарные GML/GDScript довольно просты для понимания, даже для человека, никогда не занимавшегося программированием (говорю по собственному опыту). А все эти блюпринты и их аналоги лично у меня вызывают только раздражение.
Впрочем, это исключительно дело вкуса и личных предпочтений.
Ведь главное - алгоритм, а не способ его реализации.

1

Спасибо за рускоязычные туториалы по болту, сейчас их маловато.
А вот к использованию физики в платформере на Юнити нужно относиться осторожно. Она не везде ведет себя предсказуемо. Например, использование велосити в воздухе приводит в застреваниям на краях платформ и стенах. Так что там не все так просто как кажется поначалу. Нужны дополнительные рейкасты и контроль состояний. 

3