Урок 5 из 8 · 25 мин · обновлено

Столкновения и триггеры: монеты и препятствия

Чем коллайдер отличается от триггера, как поймать момент касания через OnTriggerEnter и OnCollisionEnter, зачем нужны теги и как удалить объект из сцены. Игрок собирает монеты и теряет жизни.

Коллайдеры и триггеры

У каждого объекта, который должен с чем-то сталкиваться, есть коллайдер — невидимая форма для физики: Box, Sphere, Capsule или Mesh Collider. Примитивы из меню 3D Object получают коллайдер сразу. Зелёную рамку коллайдера видно в окне Scene, когда объект выбран.

Коллайдер бывает двух видов:

  • обычный — твёрдый: шар об него ударяется и отскакивает. Так устроены пол, стены, препятствия;
  • триггер — галочка Is Trigger в коллайдере. Объекты проходят сквозь него, а Unity только сообщает о касании. Так делают монеты, бонусы, зоны финиша и ловушки.

Чтобы события касаний сработали, хотя бы у одного объекта из пары должен быть Rigidbody. У нашего шара он есть, поэтому монетам и стенам он не нужен.

Теги

Шар может коснуться монеты, стены или финиша. Чтобы понять, что это было, объектам дают теги — метки-категории.

  1. Откройте префаб монеты и в верхней части Inspector в поле Tag выберите Add Tag…
  2. Добавьте тег Coin и назначьте его префабу. Все монеты получат тег сразу.
  3. Там же включите Is Trigger у коллайдера монеты.

OnTriggerEnter: подбираем монеты

Добавим в PlayerController поле-счётчик и метод:

C#
private int coins;

void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Coin"))
    {
        Destroy(other.gameObject);
        coins++;
        Debug.Log("Монет: " + coins);
    }
}
Результат
Монет: 1
Монет: 2
Монет: 3
  • OnTriggerEnter Unity вызывает сама в момент, когда объект входит в триггер. В other — коллайдер, которого коснулись;
  • CompareTag("Coin") проверяет тег. Шар может задеть и другие триггеры, поэтому проверка обязательна;
  • Destroy(other.gameObject) удаляет монету из сцены;
  • coins++ увеличивает счётчик на единицу.

Есть ещё OnTriggerStay — пока объект внутри триггера, и OnTriggerExit — когда вышел. Ими делают, например, зону, где персонаж лечится.

OnCollisionEnter: препятствия

Поставьте на поле несколько кубов (3D Object → Cube) с тегом Hazard и красным материалом. Is Trigger не включайте — это твёрдые препятствия. Удар о них ловит другой метод:

C#
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.

Решение
C#
void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.CompareTag("Hazard"))
    {
        lives--;
        Debug.Log("Жизней осталось: " + lives);

        if (lives <= 0)
        {
            Debug.Log("Игра окончена");
            enabled = false;
        }
    }
}

enabled = false выключает этот скрипт: шар больше не реагирует на клавиши, хотя физика продолжает его катить по инерции. В уроке 7 вместо этого покажем экран поражения.

Мини-тест: проверьте себя

Закрепите урок: несколько вопросов, разбор ответов — в конце.

  1. Шар должен проходить сквозь монету и подбирать её. Что включить у коллайдера монеты?

  2. Шар врезается в стену-препятствие. Какой метод скрипта на шаре сработает?

  3. У монеты и стены нет Rigidbody, у шара есть. Сработают ли события столкновений?

  4. Что делает Destroy(other.gameObject) в OnTriggerEnter?