Теги, слои и поиск объектов

В большой сцене сотни объектов. Как герою понять, что он коснулся именно врага, а не стены? Помогают теги и слои.

Суть: Тег (Tag) — текстовая метка объекта ("Player", "Enemy", "Coin"), по которой его можно узнать. Слой (Layer) — группировка для физики и рендера: например слой "Ground" сталкивается с игроком, а слой "UI" — нет. Это разные механизмы для разных задач.

Когда герой во что-то врезается, скрипт должен решить: это враг (получить урон), монета (подобрать) или стена (просто остановиться)? Проверять имена объектов ненадёжно. Поэтому объекты помечают тегами — короткими ярлыками, и код спрашивает: if (other.CompareTag("Enemy")).

Слои решают другую задачу — кто с кем сталкивается и кто что видит. В матрице столкновений можно задать: пули игрока бьют врагов, но не самого игрока. Это настраивается на уровне слоёв, без единой строчки кода.

Как работает под капотом

Матрица столкновений по слоям:

            Player  Enemy  Bullet  Ground
  Player      -      да     нет     да
  Enemy       да     -      да      да
  Bullet      нет    да     -       да
  Ground      да     да     да      -

"да" = объекты этих слоёв сталкиваются друг с другом.
Так пуля игрока (слой Bullet) не бьёт самого Player.

Тег и слой — независимы. У объекта может быть тег Enemy и слой Hostile одновременно. Тег чаще используют в коде для опознания, слой — для физики и рендера.

Смоделируем диспетчеризацию столкновения по тегу на Python:

# У героя есть здоровье и монеты. Реакция зависит от тега объекта
state = {"hp": 100, "coins": 0}

def on_collision(tag):
    if tag == "Enemy":
        state["hp"] -= 20
        return "Ой! Получили урон"
    elif tag == "Coin":
        state["coins"] += 1
        return "Подобрали монету"
    elif tag == "Ground":
        return "Стоим на земле"
    return "Просто столкновение"

for tag in ["Coin", "Enemy", "Ground", "Coin"]:
    print(on_collision(tag), "| hp:", state["hp"], "монеты:", state["coins"])

Та же логика на Python ▶ — ровно так в Unity скрипт реагирует на столкновение: смотрит тег второго объекта и решает, что делать. Это сердце игрового взаимодействия.

Отдельная тема — как достать ссылку на другой объект. Есть два пути: перетащить объект в поле скрипта прямо в Inspector (быстро, надёжно) или найти его в коде через GameObject.FindWithTag("Player"). Первый способ предпочтительнее: он быстрее и не ломается при переименованиях.

Частые ошибки

  • Сравнивать теги через ==. Сравнение gameObject.tag == "Enemy" работает, но CompareTag("Enemy") быстрее и безопаснее — используй его.
  • Опечатки в тегах. "Enemy" и "enemy" — разные теги. Опечатка тихо ломает логику без ошибки.
  • Злоупотреблять Find в Update. Поиск объектов каждый кадр тормозит игру. Найди один раз в Start и сохрани ссылку.

Best practices

  • Связывай объекты через поля в Inspector везде, где можно — это быстрее любого Find.
  • Настраивай матрицу слоёв (Edit → Project Settings → Physics 2D), чтобы лишние столкновения вообще не считались — это и логика, и оптимизация.
  • Заведи понятный набор тегов и слоёв в начале проекта и держись его.

Итоги: теги — для опознания объектов в коде (CompareTag), слои — для управления столкновениями и рендером через матрицу. Ссылки на объекты лучше задавать через Inspector, а не искать каждый кадр. Не путай теги и слои: это разные инструменты для разных задач.

Слой ещё и для рендера и рейкастов

Мы говорили про слои в контексте физики, но у них есть и вторая жизнь. Камера может рисовать только определённые слои через свою маску Culling Mask — так, например, прячут отладочную графику в финальном билде, не удаляя её. Лучи-проверки (рейкасты), которыми игра спрашивает «что под курсором?» или «есть ли земля под ногами?», тоже умеют фильтровать по слоям: луч проверки земли игнорирует слой врагов и реагирует только на Ground. Это превращает слои в универсальный инструмент фильтрации «кого учитываем, кого нет» — в физике, в рендере, в логике. Поэтому продуманный набор слоёв в начале проекта окупается многократно, а хаотичное навешивание слоёв задним числом, наоборот, порождает трудноуловимые баги.

Проверьте себя
1. Для чего обычно используют тег (Tag) объекта?
AЧтобы опознать объект в коде (например "это враг")
BЧтобы задать цвет объекта
CЧтобы ускорить рендер
DЧтобы сохранить игру
2. Что настраивает матрица столкновений по слоям (Layer)?
AЦвета объектов
BКто с кем из слоёв физически сталкивается
CГромкость звука
DСкорость объектов