В мире любой игры рано или поздно возникает вопрос: “А что происходит, когда два объекта встречаются?”. Именно для этого в Unity существует система коллизий (collision). Она позволяет объектам реагировать на столкновения, отталкиваться друг от друга, активировать определенные события или просто фиксировать факт контакта.
В этой статье мы подробно разберем, что такое коллизия в Unity, как она работает и какие инструменты предоставляются разработчикам для управления этим процессом.
1. Что такое коллизия?
Коллизия (столкновение) — это событие, которое происходит, когда два или более физических объектов в игровом мире вступают в контакт. Для того чтобы Unity мог обнаружить и обработать коллизию, объекты должны иметь Коллайдеры (Colliders) и, как минимум один из них, Rigidbody.
- Коллайдер: Определяет физическую форму объекта для движка (это не обязательно совпадает с его визуальной формой!).
- Rigidbody: Придает объекту физические свойства (массу, гравитацию, возможность перемещения под действием сил).
2. Как Unity обнаруживает коллизии?
Unity использует физический движок (PhisX, который является модификацией PhysX от NVIDIA), чтобы моделировать взаимодействие объектов. Когда два коллайдера с Rigidbody (или один коллайдер с Rigidbody и другой статический коллайдер) входят в контакт, движок вычисляет:
- Факт столкновения: Произошло ли касание?
- Точку контакта: Где именно произошло столкновение?
- Нормаль контакта: Направление, в котором объекты должны оттолкнуться.
- Силу столкновения: Насколько сильным было столкновение.
3. Компоненты для обнаружения коллизий
Для работы с коллизиями вам понадобятся два основных компонента:
3.1. Коллайдеры (Colliders)
Как уже упоминалось, коллайдер — это физическая оболочка объекта. Существуют различные типы коллайдеров:
- Примитивные: Box Collider, Sphere Collider, Capsule Collider. Они просты, эффективны и идеальны для большинства задач.
- Составные: Комбинация нескольких примитивных коллайдеров для создания более сложной формы (например, для персонажа).
- Mesh Collider: Создает коллайдер, точно соответствующий форме 3D-модели (Mesh). Используйте с осторожностью, так как он может быть ресурсоемким, особенно для динамических объектов. Рекомендуется для статических объектов (например, ландшафта).
- Wheel Collider: Специализированный коллайдер для колес транспортных средств.
3.2. Rigidbody
Компонент Rigidbody отвечает за то, чтобы объект участвовал в физических расчетах. Он добавляет объекту:
- Массу: Влияет на инерцию и силу столкновения.
- Гравитацию: Объект падает под действием силы тяжести (если она включена).
- Возможность движения: Объект может перемещаться под действием сил, импульсов и при изменении transform.position.
Важное правило: Чтобы два объекта физически взаимодействовали (отталкивались), хотя бы один из них должен иметь компонент Rigidbody. Если оба объекта статичны (без Rigidbody), они могут просто «застрять» друг в друге. Если один объект имеет Rigidbody, а другой — нет (но оба имеют коллайдеры), то объект с Rigidbody будет реагировать на столкновение со статическим объектом.
4. Типы обнаружения коллизий: Collision vs Trigger
Это критически важный аспект при работе с коллайдерами. В инспекторе у любого коллайдера есть галочка Is Trigger.
4.1. Collision (Столкновение)
- Is Trigger = False (по умолчанию):Объекты физически отталкиваются друг от друга.
Срабатывают события: OnCollisionEnter, OnCollisionStay, OnCollisionExit.
Эти события передают информацию о столкновении (Collision data), включая точки контакта, нормали и силу.
Пример: Мяч отскакивает от стены, игрок сталкивается с врагом.
4.2. Trigger (Триггер)
- Is Trigger = True:Объекты проходят сквозь друг друга, но факт пересечения регистрируется.
Срабатывают события: OnTriggerEnter, OnTriggerStay, OnTriggerExit.
Эти события передают информацию только об объекте, который вошел в триггер (Collider data).
Пример: Игрок входит в зону активации, собирает монету, попадает в ловушку.
5. События коллизий (Unity Event Functions)
Unity предоставляет специальные методы (функции), которые автоматически вызываются, когда происходят события, связанные с коллизиями и триггерами. Их нужно добавлять в скрипты, прикрепленные к объектам, у которых есть коллайдеры и Rigidbody.
5.1. Для Collision (Is Trigger = False):
- void OnCollisionEnter(Collision collision): Вызывается один раз, когда объект начинает касаться другого объекта.
- void OnCollisionStay(Collision collision): Вызывается каждый кадр, пока объект находится в контакте с другим объектом.
- void OnCollisionExit(Collision collision): Вызывается один раз, когда объект перестает касаться другого объекта.
Объект Collision содержит информацию о месте столкновения, нормали и количестве точек контакта.
5.2. Для Trigger (Is Trigger = True):
- void OnTriggerEnter(Collider other): Вызывается один раз, когда другой коллайдер входит в триггер.
- void OnTriggerStay(Collider other): Вызывается каждый кадр, пока другой коллайдер находится внутри триггера.
- void OnTriggerExit(Collider other): Вызывается один раз, когда другой коллайдер покидает триггер.
Объект Collider (переменная other) ссылается на коллайдер объекта, который вошел/вышел/находится в триггере.
6. Пример использования событий коллизий:
6.1. Пример с OnCollisionEnter (физическое столкновение)
csharp
using UnityEngine;
public class Ball : MonoBehaviour
{
void OnCollisionEnter(Collision collision)
{
// Проверяем, с чем столкнулся мяч
if (collision.gameObject.CompareTag("Wall"))
{
Debug.Log("Мяч ударился о стену!");
// Можно изменить цвет мяча, воспроизвести звук удара и т.д.
}
else if (collision.gameObject.CompareTag("Player"))
{
Debug.Log("Мяч столкнулся с игроком!");
// Например, нанести урон игроку
}
}
}
6.2. Пример с OnTriggerEnter (вход в зону)
csharp
using UnityEngine;
public class Zone : MonoBehaviour
{
// Предполагаем, что этот объект - триггер (Is Trigger = true)
// и на игроке есть коллайдер с тегом "Player"
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
Debug.Log("Игрок вошел в зону!");
// Активировать что-то (например, включить свет, запустить врагов)
}
}
void OnTriggerExit(Collider other)
{
if (other.CompareTag("Player"))
{
Debug.Log("Игрок покинул зону.");
// Деактивировать что-то
}
}
}
7. Оптимизация коллизий
- Используйте примитивные коллайдеры: Box, Sphere, Capsule гораздо быстрее, чем Mesh Collider.
- Избегайте Mesh Collider для динамических объектов: Для врагов или подвижных платформ используйте составные коллайдеры из примитивов.
- Rigidbody только там, где нужно: Не вешайте Rigidbody на все объекты, только на те, которые должны двигаться физически.
- Is Trigger вместо Collision: Если вам нужно только обнаружить вход/выход из зоны, а не физическое отталкивание, используйте Trigger. Это менее ресурсоемко.
- Слои (Layers): Настройте, какие слои могут сталкиваться друг с другом (Edit -> Project Settings -> Physics). Это позволит избежать ненужных проверок коллизий.
Заключение
Система коллизий в Unity — это мощный инструмент для создания интерактивного и реалистичного игрового мира. Понимание разницы между Collision и Trigger, а также правильное использование коллайдеров и Rigidbody, является ключом к созданию производительных и отзывчивых игр. Экспериментируйте с различными типами коллайдеров и событиями, чтобы добиться желаемого поведения объектов в вашей игре!