Практика 4. Динамика
Динамика Объектов в Unity
1. Метод Update
Unity является приложением реального времени, а именно выполняет действия с максимально возможной скоростью. Для рендеринга (визуализации, рисования графики) чаще всего это частота смены кадров, при вертикальной синхронизации с монитором 60 Гц - это 60 кадров/сек.
Каждый кадр Unity вызывает для скриптов метод Update. Получается, любое действие выполненное в нем, будет выглядеть как плавное, например смена положения каждый кадр будет выглядеть как плавное движение объекта.
Но при отсутствии синхронизации, может получиться что такое движение происходит рывками, когда кадров становится меньше или больше в данную секунду. Для этого в Unity есть переменная Time.deltaTime, которая вычисляется в секундах учитывая разницу во времени с предыдующим кадром. Используя эту переменную можно задавать скорость в секундах, а не в кадрах, что даст желаемую постоянную скорость движения.
Создайте новую сцену File - New Scene и добавьте куб с новым скриптом с названием move и содержанием как на рис. 1.
Рис. 1. Скрипт move
В данном скрипте мы передвигаем объект по X координате каждый кадр со скоростью speed, заданной через Inspector (по-умолчанию 1 ед/с). Вектор (speed, 0, 0) умножается на Time.deltaTime чтобы исключить рывки в движении и задать скорость в ед/с, а не ед/кадров.
При запуске видно как куб медленно передвигается по сцене.
2. Физическая Динамика
Движение заданное с помощью Translate не будет хорошо взаимодействовать с физическими объектами Rigidbody. Если обычные кубы просто будут проходить сквозь любые другие (рис. 2 и 4), то Rigidbody вообще ведет себя неадекватно и дрожит, пытаясь пройти насквозь (рис. 3).
Рис. 2. Зеленый куб со скриптом проходит через серый
Рис. 3. Rigidbody (Зеленый куб) со скриптом дрожит у серого
Рис. 4. Rigidbody (Зеленый куб) не толкается серым со скриптом
Дело в том, что при использовании Translate объект просто “телепортируется” в новое положение, вместо того чтобы взаимодействовать с другими объектами. При написании скриптов такого движения придется дописывать взаимодействие самим.
Объекты Rigidbody подчиняются законам механики, а именно движение базируется на силе. Скрипты могут вызвать метод AddForce для того, чтобы заставить их двигаться.
Создайте новую сцену и добавьте Rigidbody кубы в положениях -1 и 1 по оси X, добавьте плоскость на которую кубы могут упасть.
Рис. 5. Два Rigidbody куба в сцене
К кубу с X = -1 прикрепим скрипт, который при запуске толкнет его вправо, вдоль оси X.
Создайте скрипт force как на рис. 6.
Рис. 6. Скрипт force
Теперь можно увидеть как левый куб выносит правый с плоскости и сам падает с ним.
Важно заметить достаточное высокое значение вектора силы - сила была передана единственным импульсом со значительно малым временем действия, что мало изменило вектор скорости, который имел на тот момент куб. AddForce по умолчанию использует тип силы ForceType.Force, который нацелен на то, чтобы его постоянно вызывали. Так же можно перечислить другие типы, после вектора через запятую, например ForceType.Impulse, который полностью заменяет вектор скорости объекта, а не пытается корректировать прежний. Им можно резко сменить направление движение объекта Rigidbody, а единицы силы будут более приближенными к координатным единицам.
3. Счет времени в Unity
В данном инструментарии нет какого-то особого способа счета времени, кроме вещей вроде метода Destroy. Для этого опять можно воспользоваться методом Update и переменной Time.deltaTime, переводящей кадры в секунды.
Рис. 7. Скрипт таймера на 2 секунды
Скрипт толкает куб вверх каждые 2 секунды. Используется private чтобы переменная не отображалась в Inspector. Без сброса переменной t = 0 действие будет происходить каждый кадр после первых двух секунд после запуска.
Прикрепите новый скрипт с названием timer ко второму кубу, установите силу в скрипте force 500.
Комментарии
Отправить комментарий