Сцена, камера и первый объект на экране

Сцена — это уровень твоей игры. Камера — окно, через которое игрок на неё смотрит. Давай разместим первый объект и увидим его в игре.

Суть: сцена (Scene) — это контейнер для всего, что есть в уровне: объектов, света, камеры. Камера определяет, что именно видит игрок. Координаты в Unity — это X (вправо), Y (вверх), Z (вглубь).

Каждый уровень или экран игры — это отдельная сцена (файл .unity в Assets/Scenes). Главное меню, уровень 1, уровень 2 — обычно разные сцены. Внутри сцены живут объекты, и обязательно есть камера — без неё игрок ничего не увидит.

Положение любого объекта задаётся тремя числами — координатами Transform: X (влево-вправо), Y (вниз-вверх), Z (ближе-дальше). В 2D-игре мы в основном работаем с X и Y, а Z используем для порядка слоёв (что рисуется поверх чего).

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

В 2D-режиме камера обычно ортографическая — она не искажает перспективу, объекты не «сужаются» вдалеке. Параметр Size камеры задаёт, сколько мировых единиц по вертикали влезает в экран:

Мировые координаты (2D):

        +Y (вверх)
         ^
         |        * объект (x=3, y=2)
         |
  -------+-------> +X (вправо)
         |
         |   [камера смотрит на этот мир]
         v
        -Y

Чтобы создать видимый объект, в 2D добавляют спрайт — двумерную картинку. Простейший способ: GameObject -> 2D Object -> Sprite -> Square. На сцене появится белый квадрат. Это и есть наш первый объект.

Логика «попадает ли точка объекта в кадр камеры» — это простая проверка диапазона. Посмотрим на Python:

# Камера: центр (cam_x, cam_y), половина ширины и высоты обзора
cam_x, cam_y = 0.0, 0.0
half_w, half_h = 8.0, 4.5   # ortho size 4.5, экран 16:9

objects = [("герой", 3, 2), ("враг", 20, 0), ("монета", -5, -3)]

for name, x, y in objects:
    visible = (cam_x - half_w <= x <= cam_x + half_w) and (cam_y - half_h <= y <= cam_y + half_h)
    print(f"{name}: {'в кадре' if visible else 'за кадром'}")

Та же логика на Python ▶ — так движок решает, рисовать объект или нет. Объект «враг» на x=20 за кадром, его не видно. Это называется отсечением (culling) и экономит ресурсы.

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

  • Объект создан, но не виден. Чаще всего он за камерой по оси Z или его координата Z не совпадает с плоскостью спрайтов. В 2D держи спрайты на Z = 0, а камеру отодвинь по Z назад.
  • Забыть про камеру. Если случайно удалить Main Camera, Game View станет пустым. У сцены всегда должна быть хотя бы одна камера.
  • Гигантский или микроскопический объект. Проверяй Scale в Transform: масштаб 1 — нормальный размер, 100 — объект во весь экран.

Best practices

  • Держи камеру с тегом MainCamera — многие скрипты ищут камеру именно по нему.
  • В 2D ставь Z объектов в 0, а порядок отрисовки регулируй через Sorting Layer и Order in Layer, а не через Z вручную.
  • Сразу настрой разрешение в Game View (например 1920x1080), чтобы видеть игру так, как увидит игрок.

Итоги: сцена — контейнер уровня, камера — окно игрока, координаты — X/Y/Z. Первый объект в 2D — это спрайт (например квадрат). Если объект не виден, проверь камеру, ось Z и масштаб. Камера сама отсекает то, что вне кадра, экономя ресурсы.

Pixels Per Unit и размер мира

Есть тонкость, которая сбивает с толку новичков в 2D: связь пикселей картинки и мировых единиц. У каждого импортированного спрайта есть параметр Pixels Per Unit (по умолчанию 100). Он говорит, сколько пикселей картинки помещается в одну мировую единицу. Спрайт 100 на 100 пикселей при PPU=100 займёт ровно 1 на 1 единицу мира. Если твои спрайты кажутся гигантскими или микроскопическими — почти всегда дело в PPU, а не в Scale объекта. Договорись с собой о масштабе с самого начала (например «1 единица = 1 тайл уровня») и держи единый PPU для всех спрайтов набора. Тогда объекты будут стыковаться по размеру, физика поведёт себя предсказуемо, а камера покажет именно то, что ты ожидаешь.

Проверьте себя
1. За что отвечает камера в сцене?
AЗа физику объектов
BОпределяет, что именно видит игрок
CЗа звук
DЗа сохранение игры
2. Где в 2D-игре обычно держат спрайты по оси Z?
AНа Z = 100
BНа Z = 0, а порядок задают через Sorting Layer / Order in Layer
CНа случайных значениях Z
DZ не существует в 2D