Физика
Чтобы физическое поведение было правдоподобной, объект в игре нужно правильно ускорить и задействовать столкновения, гравитацию и другие силы. Встроенный в Unity физические движки обеспечивают вас компонентами для обработки симуляции физики. С помощью настройки всего нескольких параметров, можно создать объекты, которые ведут себя пассивно реалистично (т.е., они будут перемещены в результате столкновений и падений, но не начнут двигаться сами по себе). Управляя физикой из скриптов, вы можете придать объекту динамику автомобиля, машины или даже подвижного куска ткани. На этой странице рассматриваются основные компоненты физики в Unity со ссылками для дальнейшего чтения.
Примечание: На самом деле в Unity есть два отдельных физических движка, один для 3D физики и один для 2D физики. Основные понятия идентичны в обоих движках (за исключением дополнительного измерения в 3D), но они реализованы с разными компонентами. Так, например, существует компонент Rigidbody для 3D физики и аналогичный Rigidbody 2D для 2D физики.
See the Knowledge Base Physics section for troubleshooting, tips and tricks.
Применить физику к 2D-объектам
Сначала на сцену надо добавить любые картинки (спрайты). На картинке ниже добавлены прямоугольник и шар.
И к шару добавить компонент Rigidbody 2D, которая добавит для него поведение по правилам физики.
Шар начнёт падать, но он упадёт сквозь прямоугольник. Чтобы шар соприкосался с прямоугольником, надо обоим предметам добавить компоненты. Для шара Circle Collider 2D, а для прямоугольника Box Collider 2D.
Теперь при запуске игры, шар упадёт на прямоугольник, и начнёт скатываться с него.
Обновлено: 30 декабря 2020
Комментарии
Авторизуйтесь, чтобы добавлять комментарии
Физический 2D материал
Physics Material 2D используется для настройки трений и отскакиваний, которые происходят между 2D физическими объектами при их столкновении. Создать 2D физический материал можно через меню Assets ( Assets > Create > Physics Material 2D ).
Свойства
Свойство: | Функция: |
---|---|
Friction | Коэффициент трения для данного коллайдера. |
Bounciness | Степень отскока столкновений от поверхности. Значение 1 означает что нет отскока, в то время как значение равное 1 означает хорошую отскакиваемость без дальнейшей потери энергии. |
Детали
Для использования 2D физического материала, просто перетащите его на объект к которому привязан 2D коллайдер и перетащите его на компонент коллайдера в инспекторе. Заметьте, что для 3D физики эквивалентный ассет упоминается как Physic Material (т.е. без S в слове physic) — для скриптинга важно, чтобы не возникал конфликт между двумя командами.
Оптимизируем работу с физикой в Unity
В данном материале будет рассмотрено несколько полезных приёмов использования физики в играх и примеры их практического применения. Предполагается, что у читателя уже есть опыт разработки на Unity.
Слои и Матрица Коллизий
Все игровые объекты в Unity, если не указано иного, создаются на слое Default , где всё со всем сталкивается, но это не очень эффективно. Однако мы можем обозначить, что с чем должно взаимодействовать, определив разные слои для разных типов объектов. Для каждого нового слоя добавляются свои строка и столбец в Матрице Коллизий, которая отвечает за определение коллизий между слоями. По умолчанию, когда вы добавляете новый слой, Матрица Коллизий определяет столкновения этого слоя со всеми остальными слоями. Путём правильной настройки слоев и Матрицы Коллизий вы избежите незапланированных столкновений и сможете тестировать события коллизий.
Для целей данной статьи была создана простая демо-сцена с 2 000 объектов (1 000 красных и 1 000 зелёных) внутри контейнера. Зелёные объекты должны взаимодействовать только сами с собой и со стенами (слой Wall ). В одном из тестов все объекты принадлежат слою Default и столкновения производятся путём строкового сравнения тега игровых объектов на слушателе коллизий. В другом тесте объекты разделены на два слоя. Взаимодействие этих слоёв было настроено в Матрице Коллизий.
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
Изображение ниже берётся из самой демонстрации. В ней есть простой менеджер, который считает количество столкновений и автоматически останавливается после 5 секунд. Количество ненужных столкновений в варианте с общим слоем впечатляет.
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
Вот результат профилировки для более конкретных данных о физическом движке
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
Как мы видим, существуют значительные различия во времени, которое процессор потратил на физику. На общем слое это ~27,7 мс, а на отдельных — ~17,6 мс.
Рейкастинг
Рейкастинг — довольно полезный и мощный инструмент в физическом движке. Он позволяет направлять луч определённой длины в определённом направлении и получить информацию о произошедших столкновениях. Однако это дорогостоящая операция. Производительность рейкастинга сильно зависит от длины луча и типов коллайдеров на сцене.
Вот несколько советов по использованию рейкастинга:
- Хоть это и очевидно, но нужно стремиться к наименьшему количеству лучей.
- Не делайте лучи длиннее, чем это необходимо. Чем длиннее луч, тем больше объектов нужно проверять на столкновение с ним.
- Не используйте рейкасты внутри метода FixedUpdate() . А в некоторых случаях даже использование их внутри метода Update() может быть излишним.
- Будьте осторожнее с типами коллайдеров, которые используете. Рейкастинг с меш-коллайдером обходится довольно дорого.Неплохое решение — создать дочерний объект с примитивными коллайдерами и повторить с их помощью приблизительную форму меша. Все дочерние коллайдеры у родительского Rigidbody ведут себя как составные коллайдеры.Если вам очень нужно использовать меш-коллайдеры, то как минимум сделайте их выпуклыми.
- Уточняйте, во что именно луч должен попадать, и по возможности конкретизируйте слой-маску в функции рейкаста.Хоть это и описано в документации, но не забудьте, что то, что вы указываете в функции рейкаста, это не идентификатор слоя, а битовая маска.Если вы хотите, чтобы луч сталкивался с объектом, который находится на слое с идентификатором 10, вам необходимо указать 1
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
Здесь ведётся управление количеством и длиной лучей, чтобы получить данные профилировки. Мы можем увидеть на графике ниже зависимость производительности с той длиной лучей и их количеством, что мы имеем.
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
А вот что будет, если поменять примитивные коллайдеры на меш-коллайдеры.
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
Как вы можете видеть на данных профилировки, рейкастинг меш-коллайдеров заставляет физический движок работать больше.
Физика 2D vs 3D
Решите, какой физический движок лучше подходит для вашего проекта. Если вы разрабатываете 2D-игру или 2.5D (псевдотрёхмерность), то использование физического движка для 3D может быть избыточным. Дополнительное измерение в вашем проекте впустую загружает процессор. Вы можете посмотреть более детальные различия между двумя движками в статье.
Rigidbody
Компонент Rigidbody — это привычный компонент для физических взаимодействий между объектами. Даже когда вы работаете с коллайдером как с триггером, вам нужно добавить его на игровой объект для корректной работы событий OnTrigger . Игровые объекты, которые не имеют компонента Rigidbody, рассматриваются как статические коллайдеры. Это крайне важно, т. к. попытка сдвинуть статический коллайдер крайне неэффективна, ведь движок пересчитывает весь физический мир заново. К счастью, профайлер даст вам знать, если вы попытаетесь сдвинуть статический коллайдер, и выведет предупреждение во вкладке профайлера. В следующем тесте были убраны Rigidbody со всех движущихся объектов первой демо-сцены и засняты данные профилировки, чтобы продемонстрировать, как влияют попытки сдвинуть статические коллайдеры.
На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.
Как вы можете видеть, около 2 000 предупреждений генерируется на каждом игровом объекте. Также средние затраты времени, потраченного ЦПУ на физику, возросли с ~17,6 мс до ~35,85 мс. Поэтому если мы двигаем игровой объект, важно добавить на него Rigidbody . Если вы хотите вручную контролировать его движение, то просто пометьте его как Kinematic в свойствах Rigidbody .
Фиксированные временные участки (Timestep)
Настройка значения фиксированных timestep в Time Manager непосредственно влияет на FixedUpdate() и частоту обновления физики. Изменяя это значение, вы можете достигнуть золотой середины между точностью и временем, затраченным ЦПУ на физику.
Заключение
Все эти приёмы довольно просты в реализации, но они, несомненно, влияют на производительность вашего проекта, ведь почти каждая разрабатываемая игра использует физический движок, даже если это только обработка коллизий.