Нажми — и увидишь, что делает команда
- ⏱ Сколько займёт
- 30–50 минут, 5 шагов. Каждый шаг заканчивается результатом на экране.
- 💻 Что нужно
- Компьютер с Windows или macOS. Понадобится Unity — бесплатная для учёбы, поставим на первом шаге. С телефона этот квест не проходится.
- ⏸ Если прервёшься
- Ничего не потеряется: прогресс сохраняется на этом устройстве. Вернёшься — продолжишь с того же шага.
- 🎓 Чему научишься
- движение и физика · поворот к курсору · плавная камера
WASD под водой
В прозрачной воде под мостками ходит тень. Длинная.
«Не бойся, это твоя», — Марк смеётся. — «Сегодня ты не убегаешь от хищника. Сегодня ты и есть хищник».
Хищник поворачивается туда, куда смотрит, и не дёргается рывками — плывёт. Камера идёт следом, чуть отставая, будто её тянут на верёвке.
Ролик 3D — он про ощущение управления, а не про твою сцену. Ты соберёшь то же самое в 2D: плоская акула, курс по курсору, камера с отставанием. Приёмы одинаковые, картинка другая.
Читать текстом
Сегодня — движение, повороты и первое серьёзное условие в C#.
using UnityEngine; using UnityEngine.InputSystem; public class PlayerMovement : MonoBehaviour { [SerializeField] private float speed = 2f; private Rigidbody2D body; private void Awake() => body = GetComponent<Rigidbody2D>(); private void Update() { Keyboard kb = Keyboard.current; float hor = 0f; if (kb.dKey.isPressed || kb.rightArrowKey.isPressed) hor += 1f; if (kb.aKey.isPressed || kb.leftArrowKey.isPressed) hor -= 1f; float ver = 0f; if (kb.wKey.isPressed || kb.upArrowKey.isPressed) ver += 1f; if (kb.sKey.isPressed || kb.downArrowKey.isPressed) ver -= 1f; Vector2 move = new Vector2(hor, ver).normalized; body.linearVelocity = move * speed; } }
[SerializeField] — «покажи это поле в Инспекторе, но чужому коду не отдавай». Так настраивают скорость мышкой, не открывая файл. GetComponent находит деталь на том же объекте. || читается «или».Повесь скрипт на акулу: перетащи файл из окна Project прямо на объект в Hierarchy.
Проверь заранее: на Player должен висеть Rigidbody 2D с Gravity Scale = 0 (ставили в первом квесте). Нет его — GetComponent вернёт пусто, и Console встретит тебя красной строкой NullReferenceException.
Почему .normalized
.normalized её скорость станет примерно в 1,41 раза выше, чем по прямой: длина вектора (1, 1) равна корню из двух. Игроки такое находят мгновенно и начинают всюду бегать зигзагом. .normalized укорачивает вектор до единицы, сохраняя направление.Эта мелочь встречается в каждой игре с движением по восьми направлениям. Теперь ты про неё знаешь.

- 1Hierarchy — выдели акулуСписок объектов сцены. Клик по строке — и справа откроются все её детали. На кадре выбран Ground, у тебя это будет Player.
- 2Список деталей объектаСюда, ниже Mesh Renderer, встанет твой PlayerMovement.cs — перетащи файл из Project прямо на акулу. Рядом появится поле Speed: это и есть [SerializeField].
- 3Camera — на неё вешают CameraFollowКамера тоже строчка в списке. Выдели её, повесь скрипт и перетащи акулу мышкой в поле Target — пустое поле, и камера никуда не поедет.
- 4Play — проверь управлениеWASD или стрелки. Пока игра идёт, крути Speed и Smooth и сразу чувствуй разницу — но запиши удачные числа на бумажке: после Stop они сбросятся.
- 5Game — игра глазами игрокаЗдесь видно то, что видит камера. Смотри, как она догоняет акулу с опозданием: smooth 2 — лениво тянется, 15 — почти прилипла.
Это настоящий экран Unity 6 — такой же, как у тебя. Нажимай на кружки по порядку: метка покажет место, строка ниже объяснит, зачем оно. Отмечай пройденное — прогресс сохранится.
Нос по курсору
using UnityEngine; using UnityEngine.InputSystem; public class SharkRotation : MonoBehaviour { private SpriteRenderer sprite; private void Awake() => sprite = GetComponent<SpriteRenderer>(); private void Update() { Vector3 mouseScreen = Mouse.current.position.ReadValue(); Vector3 mouseWorld = Camera.main.ScreenToWorldPoint(mouseScreen); Vector3 look = mouseWorld - transform.position; look.z = 0f; transform.right = look; // нос смотрит на курсор if (look.x < 0f) // курсор слева — акула вверх ногами sprite.flipY = true; else sprite.flipY = false; } }
ScreenToWorldPoint переводит точку экрана в точку мира — без неё координаты мыши ничего не значат для сцены. У 2D-камеры мир лежит перед ней, поэтому Z у ответа получается −10; строка look.z = 0f убирает эту глубину, чтобы поворот считался только по плоскости. transform.right — «куда смотрит правая сторона объекта». Присвоил ей направление — объект развернулся.Три строки на разворот и три на анти-кувырок. Без flipY акула, повёрнутая влево, плывёт кверху брюхом — забавно, но неправильно.
Акула разворачивается, но не туда. Курсор в центре экрана, а нос смотрит в угол. Найди строку.

Камера, которая отстаёт нарочно
Если камера приклеена к герою намертво, картинка дёргается и от неё быстро устают глаза.
Поэтому камеру делают ленивой: она догоняет героя с небольшим опозданием. В студиях это называют сглаживанием, и почти в каждой большой игре оно есть.
Ещё один приём — камера чуть смещается вперёд по ходу движения, чтобы игрок видел, куда летит, а не то, откуда прилетел.
Камера едет следом
using UnityEngine; public class CameraFollow : MonoBehaviour { [SerializeField] private Transform target; // за кем ехать [SerializeField] private float smooth = 4f; // насколько плавно private void LateUpdate() { if (target == null) return; Vector3 goal = target.position; goal.z = transform.position.z; // камеру по Z не двигаем! transform.position = Vector3.Lerp(transform.position, goal, smooth * Time.deltaTime); } }
LateUpdate работает после всех Update — камера едет туда, где герой уже оказался, и картинка не дрожит. Vector3.Lerp — плавный переход между двумя точками. Поле target заполни так: выдели Main Camera в Hierarchy → в Инспекторе найди компонент Camera Follow (Script) → перетащи мышкой строку Player из Hierarchy в поле Target. Поле осталось пустым (None) — камера будет стоять на месте.Если забыть строку с goal.z, камера уедет в плоскость героя и покажет чёрный экран. Классическая ошибка первого дня.
Настрой ощущения
- 1Жми Play — игра запускается прямо в редактореПока идёт игра, значения в Инспекторе можно крутить и сразу чувствовать разницу.
- 2Поле Speed в твоём скриптеВыдели Player: в самом низу Инспектора, под физикой и коллайдером, стоит компонент Player Movement (Script), а в нём поле Speed. Оно видно, потому что в коде написано
[SerializeField]. Крути прямо во время игры. - 3Main Camera → скрипт CameraFollowПоле Smooth: 2 — камера лениво тянется, 15 — почти прилипла. Для аркады берут 5–8.
- 4Запиши удачные числа на бумажкеПосле нажатия Stop все правки, сделанные во время игры, сбросятся. Это ловушка, в которую попадают все.
- 5Проверь границы мираУплыви к краю. Хочется, чтобы дальше было море, а не пустота — растяни фон в окне Scene.
Настройка чисел — половина работы над игрой. Программист пишет код один раз, а числа крутит неделями.
Читать текстом
Задание студии: сделай ускорение по Shift. Подсказка: заведи вторую переменную fastSpeed и выбирай нужную через условие if (kb.leftShiftKey.isPressed).
Поднимай флаг.