Урок 5 из 8 · 25 мин · обновлено
Столкновения и триггеры: монеты и препятствия
Чем коллайдер отличается от триггера, как поймать момент касания через OnTriggerEnter и OnCollisionEnter, зачем нужны теги и как удалить объект из сцены. Игрок собирает монеты и теряет жизни.
Коллайдеры и триггеры
У каждого объекта, который должен с чем-то сталкиваться, есть коллайдер — невидимая форма для физики: Box, Sphere, Capsule или Mesh Collider. Примитивы из меню 3D Object получают коллайдер сразу. Зелёную рамку коллайдера видно в окне Scene, когда объект выбран.
Коллайдер бывает двух видов:
- обычный — твёрдый: шар об него ударяется и отскакивает. Так устроены пол, стены, препятствия;
- триггер — галочка Is Trigger в коллайдере. Объекты проходят сквозь него, а Unity только сообщает о касании. Так делают монеты, бонусы, зоны финиша и ловушки.
Чтобы события касаний сработали, хотя бы у одного объекта из пары должен быть Rigidbody. У нашего шара он есть, поэтому монетам и стенам он не нужен.
Теги
Шар может коснуться монеты, стены или финиша. Чтобы понять, что это было, объектам дают теги — метки-категории.
- Откройте префаб монеты и в верхней части Inspector в поле Tag выберите Add Tag…
- Добавьте тег
Coinи назначьте его префабу. Все монеты получат тег сразу. - Там же включите Is Trigger у коллайдера монеты.
OnTriggerEnter: подбираем монеты
Добавим в PlayerController поле-счётчик и метод:
private int coins;
void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Coin"))
{
Destroy(other.gameObject);
coins++;
Debug.Log("Монет: " + coins);
}
}
Монет: 1
Монет: 2
Монет: 3
OnTriggerEnterUnity вызывает сама в момент, когда объект входит в триггер. Вother— коллайдер, которого коснулись;CompareTag("Coin")проверяет тег. Шар может задеть и другие триггеры, поэтому проверка обязательна;Destroy(other.gameObject)удаляет монету из сцены;coins++увеличивает счётчик на единицу.
Есть ещё OnTriggerStay — пока объект внутри триггера, и OnTriggerExit — когда вышел. Ими делают, например, зону, где персонаж лечится.
OnCollisionEnter: препятствия
Поставьте на поле несколько кубов (3D Object → Cube) с тегом Hazard и красным материалом. Is Trigger не включайте — это твёрдые препятствия. Удар о них ловит другой метод:
private int lives = 3;
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Hazard"))
{
lives--;
Debug.Log("Жизней осталось: " + lives);
}
}
Обратите внимание на разницу: в OnTriggerEnter приходит Collider, а в OnCollisionEnter — Collision, подробности удара. Объект из него достают через collision.gameObject.
Ещё одна частая ошибка — опечатка в имени метода. Если написать OnTriggerEnter с маленькой буквы или с неправильным параметром, Unity не узнает метод и молча его не вызовет.
Попробуйте сами. Когда жизни заканчиваются, выведите в Console «Игра окончена» и отключите управление шаром. Подсказка: у любого компонента есть свойство enabled, а выключенный скрипт перестаёт получать Update и FixedUpdate.
Решение
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Hazard"))
{
lives--;
Debug.Log("Жизней осталось: " + lives);
if (lives <= 0)
{
Debug.Log("Игра окончена");
enabled = false;
}
}
}
enabled = false выключает этот скрипт: шар больше не реагирует на клавиши, хотя физика продолжает его катить по инерции. В уроке 7 вместо этого покажем экран поражения.
Мини-тест: проверьте себя
Закрепите урок: несколько вопросов, разбор ответов — в конце.
-
Шар должен проходить сквозь монету и подбирать её. Что включить у коллайдера монеты?
Триггер не мешает движению, а только сообщает о касании. Обычный коллайдер остановил бы шар, как стена.
-
Шар врезается в стену-препятствие. Какой метод скрипта на шаре сработает?
Стена — обычный коллайдер, без Is Trigger. Физический удар вызывает OnCollisionEnter. OnTriggerEnter — только для триггеров.
-
У монеты и стены нет Rigidbody, у шара есть. Сработают ли события столкновений?
Физика следит за объектами с Rigidbody. Шар двигается физикой, поэтому его касания со статичными коллайдерами она замечает.
-
Что делает Destroy(other.gameObject) в OnTriggerEnter?
other — коллайдер, в который вошёл игрок. other.gameObject — его объект. Destroy убирает этот объект из сцены.