В Unity есть несколько «типов», которые мы можем использовать для хранения данных. Анимационные кривые (Animation Curves) — один из таких компонентов, который предлагает гейм-дизайнерам и создателям игр интересные возможности, особенно при создании прототипов. Используйте их в своем проекте, например, в системе частиц для управления анимированными переменными или в компоненте источника звука для управления затуханием.
Кривая — это линейный график, который показывает реакцию (по оси Y) на изменение значения входного сигнала (по оси X). Unity использует кривые в различных контекстах, в частности, в анимации. Редакторы кривых имеют ряд различных опций и инструментов, которые вы можете использовать.
В этой заметке речь пойдет о работе с анимационными кривыми через API Unity с переменной типа AnimationCurve. Таким образом, их можно использовать для сбора и хранения данных, что полезно для анализа результатов. Кривые также совместимы со ScriptableObjects, которые, как уже говорилось в учебнике, отлично подходят для редактирования данных игрового процесса.
Анимационные кривые можно редактировать в инспекторе либо как открытые переменные, либо при сериализации. Их можно сохранять, экспортировать или загружать в режиме редактирования или во время выполнения. Редактируемые касательные позволяют контролировать форму кривой между клавишами.
Вы можете добавлять ключи, изменять их касательные и управлять кривой, чтобы найти форму, которая обеспечит нужный результат.
Оглавление
Добавление реалистичных деталей в повседневные движения и перемещения
Такой инструмент визуального дизайна, как кривая анимации, позволяет гейм-дизайнерам усовершенствовать игровой процесс без необходимости писать сложные математические или смягчающие функции.
Одним из способов использования кривых анимации является временная шкала, позволяющая добавить нюансы и детали в линейные движения. Возьмем пример с персонажем, закрывающим дверь автомобиля. Действие начинается с колебания, когда рука берется за рычаг, чтобы закрыть дверь. Сначала дверь закрывается медленно, но движение ускоряется по мере того, как дверь захлопывается, а затем заканчивается резкой остановкой, возможно, с небольшим отскоком или щелчком. Все эти движения могут быть сохранены в одной кривой для последовательности.
Как показано в этом примере, кривые анимации полезны для изменения свойств объекта с течением времени, чтобы создать естественное движение. Другие примеры использования связаны с тем, как объект движется или вращается, персонаж ускоряется или замедляется в спринте, или двигатель подает энергию на контроллер автомобиля.
Когда вы создаете кривую анимации для редактирования в Инспекторе, вы сможете оценить кривую, передав ей параметр, называемый в Unity временем.
Кривая «псевдо» крутящего момента двигателя для управления выходной мощностью двигателя
Давайте рассмотрим, как можно использовать кривую анимации для управления мощностью двигателя автомобиля. Вы можете создать «псевдо» кривую крутящего момента двигателя, чтобы определить силу, приложенную к автомобилю, на основе текущего числа оборотов двигателя (оборотов в минуту). Этот показатель увеличивается со временем, если игрок нажимает на педаль газа.
Вместо того, чтобы отображать весь диапазон оборотов для каждой передачи и автомобиля, вы можете «нормализовать» или установить обороты от 0 до 1. Созданные кривые «крутящего момента» можно сохранить и повторно использовать для других автомобилей и передач.
Установите это значение, разделив необработанное или текущее значение на максимальное значение:
normalisedCurrentRPM = currentRPM / maxRPM
Выходная мощность (ось Y) также будет определена в диапазоне от 0 до 1, чтобы редактор кривых был управляемым, а сами кривые — многоразовыми. Это значение может быть добавлено в силу перемещения транспортного средства, чтобы переместить его тело вперед по оси Z.
Вы можете создать различные результаты с такой же настройкой для других автомобилей, оставаясь между значениями 0,0 и 1,1 на кривой.
Добавление базового уравнения передаточного числа к двигателю вашего автомобиля может привести к созданию реалистично выглядящих автомобилей, которые двигаются и раскачиваются при переключении передач и достижении различных кривых мощности или одной и той же кривой в разных точках. Для этого необходимо, чтобы автомобиль имел компонент Rigidbody.
Когда вы добавите другие Rigidbodies в багажник или на задние сиденья автомобиля, автомобиль начнет двигаться по другому, что может быть интересным для миссий по доставке грузов.
Если вы не хотите использовать систему физики Unity, потому что у вас есть собственный контроллер автомобиля, вы можете создать варианты кривых без груза и с грузом и менять их местами во время выполнения, чтобы заставить автомобиль двигаться так, как вы хотите.
Хотя вы не будете использовать это часто, вы можете добавлять ключи, изменять ключи и полностью удалять ключи на кривых во время выполнения через Unity API. Это дает вам больше контроля над модификацией кривых, которая также может включать сглаживание касательных при необходимости.
Анимационные кривые позволяют создавать превосходные абстракции более сложных систем, которыми можно управлять в визуальном формате. В примере с двигателем вы можете добавлять мощность с течением времени при ускорении с помощью кривой, показанной выше (которая представляет «псевдо» коробку передач), чтобы создать ощущение, что автомобиль переключает передачи — регулируя угол наклона вверх по мере подачи мощности, а затем снова вниз, когда мощность уменьшается в верхней части каждой передачи. Это идеально подходит для создания прототипа движения автомобиля, так как вся мощность автомобиля находится на одной кривой, которая отображает все передачи, от начала первой передачи на x0,y0 до вершины пятой передачи на x1,y1.
Обороты обычно накапливаются со временем при ускорении, поэтому, по сути, вы откладываете значения во времени, подобно добавлению линейного перемещения к движущемуся объекту.
Возьмем другой пример: подвеска и движение автомобиля при движении по неровной местности, на поворотах или при передаче мощности на колеса. Улучшение рулевого управления, контроль боковых сил или проскальзывания шин — все это может управляться с помощью анимационных кривых для создания реалистичных результатов, которые можно визуально доработать.
При создании механики на основе лучевых моделей для транспортного средства, будь то парящее или колесное средство, распространенным выбором для создания эффекта «подвески» в двигателе является восходящая сила, приложенная к каждому лучу и алгоритм PID (пропорционально-интегрально-деривативный) контроллера для управления отскоком, или, в некоторых случаях, закон Гука для демпфирования. Пример этого можно увидеть в Unity’s Hover Racer Live 7/21 Cycle 4.2, наряду с примером, приведенным ниже в этом посте, с использованием ПИД-контроллера на его основе.
Алгоритм PID-контроллера — это механизм обратной связи контура управления, или контроллер, используемый во многих отраслях, включая разработку игр, когда необходима коррекция реакции. PID-контроллер рассчитывает значение ошибки как разницу между измеренной переменной процесса и желаемым заданным значением и, применительно к упругости (или нашему примеру), он может использоваться как альтернатива закону Гука. ПИД в играх также имеет практическое применение:
- Заставить транспортное средство регулировать заданную скорость в режиме круиз-контроля, при этом непредсказуемо подвергаясь воздействию других факторов, таких как переносимая масса, влияние игрока или угол наклона местности.
- Контроль точности вражеских агентов ИИ при стрельбе по игрокам, в то время как они избегают попаданий.
- Предсказание задержки в многопользовательских играх.
ПИДы можно использовать везде при разработке игр, особенно в песочницах и симуляторах, где требуется «точное и оптимизированное автоматическое управление». В Kerbal Space Program от Squad PID используется для удержания космического корабля в одном направлении.
Согласно этому исследованию, «PID-контроллер является наиболее зрелой и широко используемой технологией непрерывных систем» за пределами разработки игр.
Алгоритмы PID-контроллеров не требуют много времени для создания, но они требуют времени для балансировки; время, которое умножается в зависимости от того, сколько у вас транспортных средств. Однако при создании прототипа вы можете использовать анимационную кривую, чтобы сэкономить время или избежать технических проблем, связанных с реализацией и балансировкой нескольких PID-контроллеров.
Кривые идеально подходят для создания прототипов, поскольку их можно использовать для визуального соответствия реальным целевым эталонным примерам. Что касается пространства, то в игровом движке оно «математически идеально», без противоположных сил движения, если только они не добавлены или не включена гравитация по умолчанию. Поэтому часто проще использовать простую кривую для управления изменениями и получения реалистичных результатов.
В случае создания подвески для автомобиля, вы можете использовать кривые анимации, чтобы сообщить, сколько противодействующей силы прикладывается в зависимости от степени сжатия пружины (нормализованной между 0 и 1), вместо того, чтобы использовать PID-контроллер для создания демпфирования. В сочетании с Rigidbody и небольшим количеством сопротивления колебания отскока подавляются и подвеска автомобиля реагирует на увеличение или уменьшение нагрузки.
Чтобы определить сжатие пружины, нужно из длины пружины вычесть расстояние попадания лучей 1,0f. Независимо от длины пружины, когда она сжата на 25%, значение сжатия будет равно 0,25. Установите это значение сжатия в качестве значения X на кривой анимации, умножьте его на желаемую силу пружины (поскольку вы работаете с нормализованными значениями), а затем используйте его в AddForceAtPosition для применения восходящей силы в каждой точке цикла, основываясь на количестве точек подвеса. Никаких дополнительных нисходящих сил не требуется, кроме силы тяжести (в Unity по умолчанию -9.81f).
Вот формула:
upwardsForce = forceMultiplier * forceCurve.Evaluate(springCompressionNormalized);
rigidBody.AddForceAtPosition(hitNormal * upwardsForce, point.transform.position);
Используя соотношение «масса:сила» «13:110» и приведенную ниже кривую.
Автомобиль оседает при сжатии примерно на 50%, используя подходящие значения массы, восходящей силы и небольшого количества линейного и углового сопротивления для подавления колебаний. Это позволяет транспортному средству подпрыгивать и оседать, но не опускаться на дно, если только оно не сброшено с очень большой высоты или не перегружено игроком, добавляющим массу.
Чтобы найти хорошие значения, начните с кривой y = b^x (которая похожа на четверть круга). Поддерживайте низкое сопротивление и установите массу транспортного средства такой, какой она является в реальности. Восходящая сила затем регулируется до тех пор, пока автомобиль не сядет примерно на 50% сжатия пружины. Несколько раз подбросьте автомобиль, чтобы проверить, не проседает ли он, и посмотрите, где он проседает после отскока. Использование этого подхода для подвески автомобилей, которые ездят по неровной местности, где каждая точка сцепления с дорогой может быть получена или потеряна, позволяет создать быструю и управляемую систему подвески.
Использование кривых анимации для модели подвески может обеспечить разнообразные движения для транспортных средств — легковых автомобилей, микроавтобусов или грузовиков с плохой подвеской — а именно тех, которые постоянно проседают, подпрыгивают, как в аркадных играх, или кренятся на поворотах и шатаются при ускорении и торможении. Кривые можно использовать в сочетании с существующими системами, если вы еще не используете систему Rigidbody в Unity или свой собственный метод подвески. Вы можете использовать кривые для рулевого управления или для усиления мощности двигателя, подвески, сопротивления, скольжения шин, тормозной силы и многого другого. Анимационные кривые — это удобный и универсальный инструмент в Unity для добавления инструментов дизайна к каждому транспортному средству для визуального управления его характеристиками в инспекторе.
Ряд сфер на изображении выше был создан путем расположения последовательности жестких тел (Rigidbodies) в ряд и ограничения их свойств X и Z Freeze Position. Затем была приложена сила, направленная вверх, с помощью кривой анимации, основанной на силе сжатия, но с разными кривыми для каждой сферы, расположенными рядом друг с другом для лучшей визуализации. Вы можете использовать эту технику, чтобы найти желаемый уровень отскока для объекта или подстроить существующий отскок, чтобы сбалансировать характеристики. Как дизайнеру, возможность манипулировать характеристиками восходящей силы может помочь создать абстракции более сложных функций.
Кривые — это мощный тип данных XY-диаграмм и хотя они не являются технически совершенными, они могут помочь вам создать прототип быстрых решений по демпфированию, которые можно визуально редактировать в инспекторе и сохранять в качестве предустановок во время выполнения.
«Камера, анимация, движение, цветовые градиенты, переходы пользовательского интерфейса и многое другое… он используется везде! Понимание демпфирования — ключ к достижению отличной полировки. Одно только демпфирование может сделать разницу между плохим или хорошим опытом».
Alexis Bacot
Конечно, кривые имеют больше применений, чем просто тип данных XY для манипулирования игровым процессом. Их также можно использовать как инструмент оценки для визуального захвата данных с помощью AddKey через Unity API. Для оценки положения во времени, например, демпфирования в примере подвески автомобиля или падающих сфер, используйте AddKey(elapsedTime, currentSpringCompression) в методе, а затем вызовите этот метод и передайте captureResolution в качестве скорости повторения через InvokeRepeating. Разрешение захвата 0,1f означает, что каждые 0,1 сек к кривой добавляется ключ. Просмотрите мини-результат в Инспекторе или откройте график, чтобы увидеть полные данные.
Возвращаемся к прыгающему фургону
Давайте в последний раз посмотрим на падающий фургон. Кривая анимации указывает, сколько силы прикладывается на основе сжатия пружины, и создает результат, близкий к целевому, который будет иметь немного больше колебаний на третьем отскоке. Вы можете сравнить подвеску, созданную с помощью кривой анимации, с подвеской, созданной с помощью PID-контроллера. Единственная разница заключается в том, что результат PID умножается на силу зависания, а не на значение Y кривой анимации.
После внедрения PID и балансировки подвеска автомобиля стала ближе к цели, уменьшились колебания при движении и уменьшилось сопротивление, необходимое для подавления. К сожалению, PID необходимо балансировать для каждого автомобиля, если у них разные значения массы, что занимает много времени. Для целей прототипирования это можно сделать быстро и наглядно с помощью animation curves, а результаты движения можно проанализировать на графике. Для оценки реализации PID-контроллера, опять же, можно использовать кривую, чтобы построить график результата на пустой кривой.
Напомним, что кривые анимации используются при разработке разных элементов движения автомобиля:
- Изобразить мощность двигателя автомобиля и создать плавное изменение мощности.
- Создавать реалистичные движения при торможении, например, когда тормозное усилие быстро накладывается и затем уменьшается со временем, чтобы имитировать торможение реального автомобиля; или в игре, такой как iRacing, когда водитель тормозит на пределе шин, чтобы автомобиль замедлился за короткий промежуток времени, не выходя из-под контроля.
- Смоделировать систему подвески, которая обеспечивает подъем автомобиля вверх.
- Моделирование боковой тяги с расчетом боковой противодействующей силы, которая удерживает автомобиль от слишком сильного скольжения влево или вправо.
- Имитация рулевого управления при использовании контроллера (рулевое управление можно использовать в середине, примерно от -0,5 до 0,5, но оно становится все сильнее, когда положение стика приближается к -1 или 1).
Помимо физики транспортных средств, кривые анимации можно использовать в качестве инструментов проектирования создания прототипов движения игрока, повреждения от ударов с течением времени и многого другого. Являясь мощным инструментом создания прототипов, Animation Curves позволяют разработчикам игр тестировать применение различных сил и определять правильное «чувство» механики, не прибегая к написанию сложных алгоритмов или физическим расчетам.