Физика

Чтобы физическое поведение было правдоподобной, объект в игре нужно правильно ускорить и задействовать столкновения, гравитацию и другие силы. Встроенный в Unity физические движки обеспечивают вас компонентами для обработки симуляции физики. С помощью настройки всего нескольких параметров, можно создать объекты, которые ведут себя пассивно реалистично (т.е., они будут перемещены в результате столкновений и падений, но не начнут двигаться сами по себе). Управляя физикой из скриптов, вы можете придать объекту динамику автомобиля, машины или даже подвижного куска ткани. На этой странице рассматриваются основные компоненты физики в Unity со ссылками для дальнейшего чтения.
Примечание: На самом деле в Unity есть два отдельных физических движка, один для 3D физики и один для 2D физики. Основные понятия идентичны в обоих движках (за исключением дополнительного измерения в 3D), но они реализованы с разными компонентами. Так, например, существует компонент Rigidbody для 3D физики и аналогичный Rigidbody 2D для 2D физики.
See the Knowledge Base Physics section for troubleshooting, tips and tricks.
Rigidbody (Твердое тело)
Твёрдые тела позволяют вашим игровым объектам взаимодействовать с помощью физики. Для реалистичного перемещения твёрдых тел, на последние воздействуют сила вращения и другие силы. Любой игровой объект должен содержать в себе твёрдое тело, чтобы быть подверженным гравитации, действовать согласно назначенным путём скриптинга силам, или взаимодействовать с другими объектами через физический движок NVIDIA PhysX.

Свойства
| Свойство: | Функция: |
|---|---|
| Mass | The mass of the object (in kilograms by default). |
| Drag | Какое воздушное сопротивление оказывается на объект пока он перемещается под воздействием этих сил. 0 означает отсутствие сопротивления, а бесконечность (infinity) тут же прекращает перемещение объекта. |
| Angular Drag | Какое воздушное сопротивление оказывается на объект пока он вращается под воздействием силы вращения. 0 означает отсутствие сопротивления. Учтите что вы не можете остановить вращение объекта путём установки его углового сопротивления (Angular Drag) в бесконечное (infinity) положение. |
| Use Gravity | При включении на объект действует гравитация. |
| Is Kinematic | При включении, объект не будет управляться физическим движком, и сможет управляться только при помощи своей трансформации. Полезно при перемещении платформ или если вам необходимо анимировать твёрдое тело, которое имеет назначенный HingeJoint. |
| Interpolate | Попробуйте одну из опций если вы замечаете тряску в перемещении своего твёрдого тела. |
| — None | Не применено никакой интерполяции. |
| — Interpolate | Сглаживание транформации основано на трансформации из предыдущего кадра. |
| — Extrapolate | Сглаживание трансформации основано на приблизительной трансформации следующего кадра. |
| Collision Detection | Используется для предотвращения проникновения быстро перемещающихся объектов сквозь другие объекты без определения столкновений. |
| — Discrete | Use discrete collision detection against all other Colliders in the Scene. Other colliders will use discrete collision detection when testing for collision against it. Used for normal collisions (This is the default value). |
| — Continuous | Use Discrete collision detection against dynamic Colliders (with a Rigidbody) and sweep-based continuous collision detection against static Colliders (without a Rigidbody). Rigidbodies set to Continuous Dynamic will use continuous collision detection when testing for collision against this rigidbody. Other rigidbodies will use Discrete Collision detection. Used for objects which the Continuous Dynamic detection needs to collide with. (This has a big impact on physics performance, leave it set to Discrete, if you don’t have issues with collisions of fast objects) |
| — Continuous Dynamic | Use sweep-based continuous collision detection against GameOjects set to Continuous and Continuous Dynamic collision. It will also use continuous collision detection against static Colliders (without a Rigidbody). For all other colliders, it uses discrete collision detection. Used for fast moving objects. |
| — Continuous Speculative | Use speculative continuous collision detection against Rigidbodies and Colliders. This is also the only CCD mode that you can set kinematic bodies. This method tends to be less expensive than sweep-based continuous collision detection. |
| Constraints | Ограничения движения твёрдого тела:- |
| — Freeze Position | Выборочно останавливает перемещение твёрдого тела по осям X, Y и Z. |
| — Freeze Rotation | Stops the Rigidbody rotating around the local X, Y and Z axes selectively. |
Details
Rigidbodies allow your GameObjects to act under control of the physics engine. This opens the gateway to behaviors such as realistic collisions and varied types of joints. Manipulating your GameObjects by adding forces to a Rigidbody creates a very different feel and look than adjusting the Transform Component directly. Generally, you shouldn’t manipulate the Rigidbody and the Transform of the same GameObject — only one or the other.
Наибольшее отличие между управлением трансформациями и твёрдыми телами заключается в использовании сил. Твёрдые тела могут управляться силами и вращением, трансформации же не могут. Трансформации можно перемещать и вращать, но это не то же самое, что и использование физики. Вы заметите разницу, когда решите сами испробовать это на деле. Добавление силы/вращения к твёрдому телу позволит изменить позицию и вращение компонента трансформаций (Transform) объекта. Вот почему вам нужно использовать только один из них. Изменение трансформаций при использовании физики может создать проблемы столкновениях и других вычислениях.
Rigidbodies must be explicitly added to your GameObject before they will be affected by the physics engine. You can add a Rigidbody to your selected object from Components->Physics->Rigidbody in the menu. Now your object is physics-ready; it will fall under gravity and can receive forces via scripting, but you may need to add a Collider or a Joint to get it to behave exactly how you want.
Наследование
Когда объект находится под управлением физики, он перемещается частично независимо от своих родителей. Если вы переместите одного из родителей, они потянут за собой Rigidbody потомков. Однако, твёрдые тела также будут падать вниз под воздействием силы тяжести и реагировать на события столкновений.
Скриптинг
Чтобы контролировать свои твёрдые тела, вы будете в основном использовать скрипты для добавления сил и вращения. Вы можете это сделать, вызвав на твёрдом теле (Rigidbody) объекта AddForce() и AddTorque(). Помните что при использовании физики вы не должны напрямую менять трансформацию объекта.
Анимация
For some situations, mainly creating ragdoll effects, it is neccessary to switch control of the object between animations and physics. For this purpose Rigidbodies can be marked isKinematic. While the Rigidbody is marked isKinematic, it will not be affected by collisions, forces, or any other part of the physics system. This means that you will have to control the object by manipulating the Transform component directly. Kinematic Rigidbodies will affect other objects, but they themselves will not be affected by physics. For example, Joints which are attached to Kinematic objects will constrain any other Rigidbodies attached to them and Kinematic Rigidbodies will affect other Rigidbodies through collisions.
Коллайдеры
Коллайдеры это другой тип компонентов, которые должны быть добавлены наряду с твёрдыми телами, чтобы задействовать столкновения. Если два твёрдых тела врезаются друг в друга, физический движок не будет просчитывать столкновение, пока к обоим объектам не будет назначен коллайдер. Твёрдые тела не имеющие коллайдеров будут просто проходить сквозь друг друга при просчёте столкновений.

Добавьте коллайдер при помощи меню Component->Physics. Посетите страницу руководства компонентов для получения дополнительной информации по каждому конкретному коллайдеру:
- Box коллайдер — примитивная форма куба
- Сферический коллайдер — примитивная форма сферы
- Капсульный коллайдер — примитивная форма капсулы
- Меш коллайдер — создаёт коллайдер из меша объекта, не может сталкиваться с другим меш коллайдером
- Wheel Collider — специально для создания автомобилей и другого транспорта
- Terrain Collider — handles collision with Unity’s terrain system
Составные коллайдеры
Compound Colliders are combinations of primitive Colliders, collectively acting as a single Rigidbody. They come in handy when you have a model that would be too complex or costly in terms of performance to simulate exactly, and want to simulate the collision of the shape in an optimal way using simple approximations. To create a Compound Collider, create child objects of your colliding object, then add a Collider component to each child object. This allows you to position, rotate, and scale each Collider easily and independently of one another. You can build your compound collider out of a number of primitive colliders and/or convex mesh colliders.

На картинке сверху, игровой объект Gun Model с назначенным твёрдым телом и несколькими примитивными коллайдерами в качестве потомков игрового объекта. При движении Rigidbody родителя под воздействием сил, потомки коллайдеры будут двигаться вместе с ним в том же направлении. Примитивные коллайдеры будут сталкиваться с меш коллайдерами окружающей среды, и родительский Rigidbody изменит способ своего перемещения, основываясь на силах, применённых к нему и том, как его потомки коллайдеры взаимодействуют с другими коллайдерами в сцене.
Меш коллайдеры не могут нормально сталкиваться друг с другом. Если меш коллайдер помечен как Convex, тогда он может сталкиваться с другим меш коллайдером. Обычным выходом из ситуации будет использование примитивных коллайдеров для любых движущихся объектов, и меш коллайдеров для статичных второстепенных объектов.
Note: Compound colliders return individual callbacks for each collider collision pair when using Collision Callbacks.
Непрерывное обнаружение столкновений
Continuous collision detection is a feature to prevent fast-moving colliders from passing each other. This may happen when using normal (Discrete) collision detection, when an object is one side of a collider in one frame, and already passed the collider in the next frame. To solve this, you can enable continuous collision detection on the rigidbody of the fast-moving object. Set the collision detection mode to Continuous to prevent the rigidbody from passing through any static (ie, non-rigidbody) MeshColliders. Set it to Continuous Dynamic to also prevent the rigidbody from passing through any other supported rigidbodies with collision detection mode set to Continuous or Continuous Dynamic. Continuous collision detection is supported for Box-, Sphere- and CapsuleColliders. Note that continuous collision detection is intended as a safety net to catch collisions in cases where objects would otherwise pass through each other, but will not deliver physically accurate collision results, so you might still consider decreasing the fixed Time step value in the TimeManager inspector to make the simulation more precise, if you run into problems with fast moving objects.
Используйте правильный размер
Размер вашего игрового объекта играет большую роль по сравнению с массой твёрдого тела. Если вы заметили что ваше твёрдое тело ведёт себя не так, как вы изначально задумывали — медленно двигается, колеблется, или некорректно сталкивается — попробуйте настроить масштаб своего меш ассета. Стандартная единица измерения в Unity 1 юнит = 1 метр, Например, разрушающийся на части небоскрёб выглядит гораздо иначе нежели башня, собранная из игрушечных блоков, поэтому объекты разного размера должны быть смоделированы в масштабе.
If you are modeling a human make sure the model is around 2 meters tall in Unity. To check if your object has the right size compare it to the default cube. You can create a cube using GameObject > 3D Object > Cube. The cube’s height will be exactly 1 meter, so your human should be twice as tall.
If you aren’t able to adjust the mesh itself, you can change the uniform scale of a particular mesh asset by selecting it in Project View and choosing Assets->Import Settings… from the menu. Here, you can change the scale and re-import your mesh.
Если в вашей игре необходимо сделать так, чтобы создавались экземпляры объектов типа GameObject разного размера, будет вполне нормальным изменять значения масштаба осей трансформаций вашего объекта. Плохой стороной этого процесса является то, что физическая симуляция должна брать на себя основную часть работы во время создания экземпляров объекта, а это в свою очередь может сказаться на снижении производительности в вашей игре. Но это не ужасная потеря, и это не так уж эффективно как при использовании для масштабирования ваших объектов двух других опций. Также не забывайте о том, что неравномерное масштабирование может привести к непредсказуемому поведению при использовании наследования. Поэтому, в таких случаях лучше в своём пакете трёхмерного моделирования изначально создавать свои объекты в правильном масштабе.
Советы
- Относительная Mass двух твёрдых тел, определяющая то, как они реагируют на столкновение друг с другом.
- Установка Mass одного твёрдого тела больше массы другого твёрдого тела не подразумевает того, что при свободном падении оно будет падать быстрее. Используйте для этого Drag.
- Маленькое значение Drag заставляет объект казаться тяжёлым, а большое лёгким. Типичные значения для Drag находятся между .001 (твёрдый блок или метал) и 10 (пёрышко).
- Если вы напрямую управляете компонентом Transform своего объекта, но хотите воспользоваться физикой, тогда назначьте ему твёрдое тело (Rigidbody) и сделайте его кинематическим (Kinematic).
- Если вы перемещаете игровой объект через его компонент преобразования (Transform), но хотите получать сообщения о столкновениях/переключениях, вы должны назначить перемещающемуся объекту компонент твёрдое тело (Rigidbody).
- Вы не можете остановить вращение объекта путём установки его углового сопротивления (Angular Drag) в бесконечное (infinity) положение.
- 2018–10–12 Page amended
- Continuous Speculative collision detection method added in 2018.3
Оптимизируем работу с физикой в Unity
В данном материале будет рассмотрено несколько полезных приёмов использования физики в играх и примеры их практического применения. Предполагается, что у читателя уже есть опыт разработки на Unity.
Как быстро написать игру для Android на 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() и частоту обновления физики. Изменяя это значение, вы можете достигнуть золотой середины между точностью и временем, затраченным ЦПУ на физику.
Заключение
Все эти приёмы довольно просты в реализации, но они, несомненно, влияют на производительность вашего проекта, ведь почти каждая разрабатываемая игра использует физический движок, даже если это только обработка коллизий.

Следите за новыми постами по любимым темам
Подпишитесь на интересующие вас теги, чтобы следить за новыми постами и быть в курсе событий.
Решения для физики в играх
Создавайте детальные, интерактивные и динамические миры с реалистичной физикой.

Создавайте впечатляющие игры
Решения для физики помогают сделать игру более увлекательной. Не важно, создаете вы игру в 2D или 3D, с камерой от первого лица или видом сбоку, — ваши персонажи и предметы будут реагировать реалистично на окружающий игровой мир.
Физика для проектов на основе ECS
Решение Unity для проектов на базе Entity-Component-System (ECS) состоит из двух систем: Unity Physics и Havok Physics для Unity. Обе работают на фреймворке Unity ECS, поэтому они используют один и тот же протокол данных.
Это позволяет без проблем заменять одну физическую систему на другую без необходимости перерабатывать контент или код игры. Независимо от используемой системы, будь то Unity Physics или Havok Physics, универсальный протокол данных позволяет использовать разработанный контент для моделирования на любом физическом движке с поддержкой ECS.
- Unity Physics
- Havok Physics для Unity

Unity Physics
Быстро. Экономично. Без кэширования. Гибко. Именно эти качества отличают наше новое решение Unity Physics.
Созданное на основе фреймворка Unity ECS, это решение готово для работы в сети, полностью настраивается и обеспечивает высокую производительность даже при стандартной реализации. От мобильных до многопользовательских консольных игр, решение Unity Physics, использующее преимущества компилятора Burst и новой системы задач, масштабируется в соответствии с любыми ограничениями аппаратных систем.
Решение Unity Physics будет доступно в технической версии Unity 2022.2 через менеджер пакетов.

Havok Physics для Unity
Havok Physics для Unity предоставляет улучшенные возможности моделирования физики и удобную интеграцию с проектами на базе ECS. Тогда как решение Unity Physics оптимизировано для большинства случаев использования RT3D, решение Havok Physics для Unity может улучшить стабильность и производительность физики в больших открытых мирах или сценах с огромным количеством твердых тел. Бэкенд Havok Physics для симуляции в Unity можно в любое время заменить на бэкенд Unity Physics, не меняя существующие ассеты или код физики.
Havok Physics для Unity будет доступен в технической версии Unity 2022.2.
Физика для объектно ориентированных проектов
Если вы работаете над объектно-ориентированным проектом, можете выбрать один из двух физических движков, которые подходят для разработки 3D- и 2D-игр.
- Встроенная физика для 3D-игр
- Встроенная физика для 2D-игр

Встроенная физика для 3D-игр: интеграция NVIDIA PhysX
Встроенный движок физики для 3D-игр в Unity представляет собой интеграцию движка PhysX, которая была разработана в тесном сотрудничестве с NVIDIA. Движок PhysX доступен прямо в редакторе.
NVIDIA PhysX SDK — это масштабируемый физический движок реального времени с открытым исходным кодом, который обеспечивает сложные симуляции для более иммерсивной игры с реалистичным моделирование и динамическими эффектами в реальном времени. PhysX — это библиотека представления 3D-миров, которая позволяет создавать и разрушать объекты, и отслеживает их прямые или непрямые взаимодействия.
Среди прочего, PhysX SDK поддерживает такие возможности моделирования динамики, как столкновения, сочленения и приведение в действие с помощью максимальных и/или обобщенных координат. Вы также можете опрашивать мир, используя различные инструменты, например проверки raycast, sweep и overlap.

Встроенная физика для 2D-игр
Unity поставляется с физическим движком для 2D-игр с большим количеством функций и оптимизаций для вашей игры.
2D-коллайдеры позволяют точно определять как примитивную, так и пользовательскую форму спрайтов. Если к объектам также добавить компонент Rigidbody 2D, они будут реагировать на гравитацию и вести себя как твердые тела.
Вы также можете воспользоваться преимуществами физики для тех объектов, которые прикреплены к другим: добавьте компонент 2D Joints, чтобы создать реалистичную движущуюся платформу, цепь, пружину или автомобиль. Чтобы смоделировать плавучесть или магнетизм, можно добавить бесконтактные физические эффекты с помощью компонента 2D Effectors.
Ресурсы

Примеры физики в DOTS
В помощь вам мы подготовили репозиторий примеров использования возможностей Physics в DOTS. Примеры Unity Physics включены в число примеров ECS на GitHub.