Создаем 2D игру на Unity: пошаговое руководство для начинающих
Подготовка среды и инструментария
Первый шаг, с которого мы создаем 2D игру на Unity, — это грамотная настройка среды разработки. Несмотря на дружелюбие Unity к новичкам, важно не теряться в необязательных настройках и сразу изолировать всё, что нужно для комфортной и продуктивной работы.

Версия Unity для старта: всегда выбирайте LTS-сборку (Long Term Support). Это стабильная, проверенная версия. Поддержка важна: вы избежите неожиданных багов, обрушений и сложностей с совместимостью. На начало 2024 года — актуальна Unity 2022.3 LTS.
Установка: скачайте Unity Hub. Это централизованная панель управления проектами, версиями и лицензией. Через неё вы можете установить необходимые модули (платформы, редакторы, документацию).
- Установите Unity Editor с модулем под вашу ОС (Windows или macOS);
- Добавьте модули сборки, если вы планируете делать WebGL или Android-платформу — это можно сделать позже;
- Выберите шаблон “2D Core” при создании проекта — он очищенный от 3D-зависимостей и отлично подходит для 2D-механик.
Язык программирования: Unity использует C#. Если вы не знакомы с ним, достаточно базовых знаний: переменные, условия, циклы, методы. Для стартового понимания подойдут:
- Официальный гайд от Microsoft;
- Unity Learn — платформа с заданиями и туториалами;
- Youtube-каналы: Brackeys (архив), GameDev Guide — простые и визуальные;
Интерфейс редактора:
- Scene — визуальное представление мира игры;
- Game — результат, который увидит игрок;
- Hierarchy — список всех объектов на сцене;
- Project — иерархия всех файлов и assets проекта;
- Inspector — показывает параметры выбранного объекта или компонента;
- Console — сообщения от скриптов, предупреждения, ошибки.
Рекомендуется изменить фон IDE на тёмный режим (Editor Theme), чтобы снизить утомляемость глаз. Это доступно в Unity, начиная с бесплатной лицензии Personal.
Организация Assets: заранее создайте папки:
- Scripts — для всех .cs файлов;
- Sprites — изображения, визуальные ассеты;
- Prefabs — повторно используемые объекты;
- Scenes — уровни игры;
- UI — всё, что относится к интерфейсу;
- Audio — при необходимости, звуки и музыка.
Это обеспечит чистоту проекта и сэкономит часы при масштабировании. Хорошая практика — использовать префиксы в названиях файлов (например, UI_ScoreText), чтобы в текстовом поиске быстро находить то, что нужно.
После запуска редактора и создания проекта — вы уже внутри сцены. Перед вами пустой холст, который скоро превратится в работающую игру. Время двигаться дальше.
Описание концепции и механики будущей игры
Прежде чем писать код или искать изображения героев, нужно чётко ответить себе: во что человек будет играть? Без заранее понятной концепции даже простая mechanics-heavy игра может стать бессвязным набором действий.
Выбор формата: для первой игры критически важно не завышать планку. Идеальны шорт-механики:
- Endless runner — персонаж бежит вправо, избегая препятствий и собирая очки;
- Top-down shooter — управление кораблём, уничтожение врагов с видом сверху;
- Кликер — игрок нажимает, чтобы производить ресурсы, апгрейдить параметры;
- Платформер — прыжковая механика, тайминговые вызовы и ловушки.
Мини-документация (даже на листе бумаги):
- Жанр: платформер;
- Цель игрока: пройти уровень, избежав врагов;
- Основные действия: движение, прыжок, возможно стрельба;
- Противники: охранники-патрули, шипы;
- Условия завершения: добраться до выхода или собрать ключи.
На этом этапе стоит решить: будет ли игра иметь уровни или бесконечный режим; нужна ли прогрессия; требуется ли хранилище результатов. Чем яснее вы это понимаете заранее — тем проще реализовать.
Пример простой игровой механики: игрок управляет персонажем, который бежит по автоматически прокручивающемуся миру (parallax background). Клики мыши/тач — прыжок. Враг — двигающийся GameObject с BoxCollider2D. Столкновение = поражение.
Такой шаблонный проект можно развить до бесконечности: бонусы, смена обстановки, уровни сложности, улучшения. Но на старте важна главная идея: игра должна быть понятна и играбельна в течение 20 секунд после запуска.
Вопрос к себе: назовите игру, в которую вы «залипали» дольше 30 минут, не осознавая времени. Почему это происходило? Попробуйте воссоздать этот крючок в своей механике.
Создание сцены и интерфейса: визуальная основа
Теперь, когда идея игры сформирована, начинаем собирать визуальную сцену. Этот этап наиболее вдохновляющий — за пару часов можно увидеть свои задумки в действии.
Сцена по умолчанию включает: Main Camera и Directional Light (в 2D можно удалить его). Начинаем наполнять её объектами:
- Создайте пустой объект Environment; в него поместите землю, фон, платформы;
- Добавьте
Spriteв сцену:Right Click → 2D Object → Sprite; - Импортируйте изображения в папку
Sprites; Unity автоматически распознает.pngкак спрайт. ВыберитеSprite (2D and UI)в настройках texture type.
Важно: соблюдайте одинаковый пиксель-денсити и разрешения. Если фон весит 4 Мб, а герой — 12 Кб и в разных стилях, игра будет выглядеть «поросячьей сборкой». Лучше использовать готовые ассеты из Unity Asset Store:
- Kenney assets — открытые лицензии, аккуратные стили;
- Pixel Adventure, SunnyLand, Tiny Heroes — часто используются в туториалах;
Parallax Background: для ощущения глубины добавьте 2–3 слоя фонов с разной скоростью движения. Создайте несколько пустых объектов на разных слоях (настройте их Sorting Layer), прикрепите SpriteRenderer и плавно передвигайте слои скриптом.
Создание игрока:
- Добавьте GameObject и примените спрайт героя;
- Прикрепите компонент
Rigidbody2Dдля физики; - Добавьте
BoxCollider2D(илиPolygonCollider2Dдля сложной формы); - Закрепите тег “Player” для дальнейшей логики interactivity и коллизий.
Интерфейс игры (HUD):
- Создайте
Canvas→UI → Text(илиTextMeshPro); - Разместите счётчик очков, жизней и кнопку restart;
- Добавьте
UI → Buttonс методом OnClick, привязанным к скрипту рестарта.
Советы UI-организации: используйте Canvas Scaler с параметром Scale with Screen Size, чтобы интерфейс оставался прямопропорционален разрешению экрана. Используйте контейнеры: VerticalLayoutGroup, HorizontalLayoutGroup для автоматического расположения элементов.
Сейчас ваша сцена обрела базовую визуальную основу. Камера показывает мир, игрок стоит на платформе, фон двигается, интерфейс реагирует. Это достижение — а теперь начнём оживлять мир.
Управление персонажем и взаимодействие
Живая игра начинается с реакции на действия пользователя. Когда герой двигается, прыгает, стреляет — появляется ощущение контроля. Именно здесь зарождается геймплей. Мы рассмотрим, как добавить скрипты, чтобы персонаж начал реагировать на нажатия клавиш, столкновения и другие игровые события.
Базовое движение персонажа: создайте новый C# скрипт, назовите его PlayerController и прикрепите к игровому объекту персонажа. Внутри скрипта реализуется логика движения:
public class PlayerController : MonoBehaviour
{
public float moveSpeed = 5f;
public float jumpForce = 10f;
private Rigidbody2D rb;
private bool isGrounded = true;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
float xInput = Input.GetAxis("Horizontal");
rb.velocity = new Vector2(xInput * moveSpeed, rb.velocity.y);
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
isGrounded = false;
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.contacts[0].normal.y > 0.5)
{
isGrounded = true;
}
}
}
Пояснение к коду:
Input.GetAxis("Horizontal")возвращает -1 до 1 в зависимости от нажатой клавиши (A/D или стрелки);Rigidbody2Dуправляет физикой; скорость обновляется при каждом кадре;- Прыжок выполняется через
AddForce()с проверкой — можно прыгнуть только с земли; - Коллизия проверяется по нормали — чтобы прыгать только при касании верха (не боковая стена);
Такой подход обеспечивает контроль и предотвращает баги с множественными прыжками в воздухе.
Анимации и их переключение: если используете анимированного персонажа, не забывайте о Animator Controller. В нём можно создать состояния (idle, run, jump) и переключать их через параметры:
animator.SetBool("isRunning", xInput != 0);
animator.SetBool("isGrounded", isGrounded);
Добавьте компонент Animator к персонажу и свяжите его с заранее подготовленным animator controller.
Физика и Collider’ы: без коллизий персонаж может “провалиться” сквозь землю. Убедитесь, что у вашего пола и платформ есть компонент BoxCollider2D или TilemapCollider2D (если использовали Tilemap). Игровой объект персонажа должен иметь как минимум:
Rigidbody2D(Body Type: Dynamic);BoxCollider2D(можно использоватьCapsuleCollider2Dдля улучшенного касания);
Для скользящего или «липкого» поведения на платформах, проверьте настройки:
- Добавьте слой ground и укажите на нём платформу;
- В настройках Physics2D включите «Friction» минимальную (0), если персонаж тормозит слишком резко;
- Используйте
PhysicsMaterial2Dс настроенными значениями;
Debugging и отладка: часто проблема не в коде, а в порядке выполнения или состава компонента. Используйте:
Debug.Log("Player Jumped!");
Добавляйте это по ключевым точкам логики, чтобы видеть порядок действий. Unity Console покажет сообщение, если условие выполнено.
Как проверить плавность: обратите внимание на отзывчивость управления. Если персонаж «тормозит» или слишком резко меняет анимацию — поработайте с параметрами:
moveSpeedиjumpForce— регулируют ощущение физики;- Частота FixedUpdate() — влияет на стабильность физики (изменять только с пониманием);
- Линейная интерполяция Rigidbody — сглаживает перемещения;
Добавляя эти подробности, игрок получает тот самый геймфлоу. Автоматические реакции в момент нажатия создают удовольствие и вовлечённость.
Препятствия, враги и простейшая логика AI
Вовлечённость игрока во многом зависит от вызовов. Угроза поражения, необходимость уклоняться, выбирать момент — всё это требует сценариев поведения объектов, которые не просто стоят — они “живут”.
Начнем с простых врагов-патрульных. Это объекты, у которых есть движение туда-обратно, иногда со сменой спрайта или анимации:
public class EnemyPatrol : MonoBehaviour
{
public float speed = 2f;
public Transform pointA;
public Transform pointB;
private Vector3 target;
void Start()
{
target = pointB.position;
}
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
if (Vector3.Distance(transform.position, target) < 0.1f)
{
target = target == pointA.position ? pointB.position : pointA.position;
Flip();
}
}
void Flip()
{
Vector3 scale = transform.localScale;
scale.x *= -1;
transform.localScale = scale;
}
}
Объяснение:
- Враг перемещается между двумя точками (
GameObjectс позициями); - По достижении цели — инвертирует масштаб по оси X, создавая эффект разворота;
Для AI-преследования (простой зомби-гонщик):
public Transform player;
void Update()
{
float distance = Vector2.Distance(transform.position, player.position);
if (distance <= 5f)
{
transform.position = Vector2.MoveTowards(transform.position, player.position, speed * Time.deltaTime);
}
}
Реакция на столкновение: используйте OnCollisionEnter2D(Collision2D collision) или OnTriggerEnter2D(Collider2D other) — второй требует включённого флага «Is Trigger». Создайте HealthSystem:
public int health = 3;
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("Enemy"))
{
health--;
if (health <= 0)
{
Die();
}
}
}
Обратите внимание: у игрового объекта “враг” должен быть назначен тег Enemy, чтобы использовать CompareTag(). Это предпочтительнее, чем проверка по имени объекта — ускоряет исполнение и упрощает код.
Враг с анимацией: используйте Animator Enemy’а, переключайтесь на "Attack" или "Dead" состояние в зависимости от события:
animator.SetTrigger("Attack");
Ловушки: добавьте объекты со спрайтами и BoxCollider2D (Is Trigger = true). При контакте с игроком вызывайте событие потери жизни.
Балансировка: на старте создавайте 1 врага и 1 ловушку. Если игрок умирает дважды за 10 секунд игры — усложнение неуместно. Используйте формулу:
- 1 вызов в 7–10 секунд — поддерживает тонус мозга и интерес;
- 3 разных типа опасности на одном уровне даёт разнообразие, но не перегружает;
Плейтест: пригласите 1–2 знакомых пройти уровень. Наблюдайте: где они застряли? Слишком сложно? Или скучно? Дайте им попробовать без подсказок. Это даст больше понимания, чем неделя автотестов.
Теперь у вас есть враги, которые двигаются, живут логикой, и взаимодействуют с игроком. Механика получила игру в ответ — игрок начинает воспринимать события как реакцию мира, а не шаблон сценария.
Сохранение прогресса, счётчики и геймплейные циклы
Настало время придать вашей игре структуру полноценного игрового цикла. Отслеживание очков, возможность начать заново, сохранение достижений — всё это обеспечивает ощущение законченности и мотивацию к повторным попыткам. В этом разделе мы внедрим основные игровые элементы: счётчики, сохранения и систему «игра — поражение — перезапуск».
Счётчики очков и сбор предметов: добавьте в игру предметы (например, звёзды или монеты). Это обычные GameObject с BoxCollider2D, настроенным как Is Trigger. При столкновении с игроком предмет исчезает, а счёт увеличивается:
int score = 0;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Coin"))
{
score += 10;
Destroy(other.gameObject);
UpdateScoreUI();
}
}
Не забудьте задать тег Coin вашему объекту. Функция UpdateScoreUI() обновляет текстовое поле TextMeshProUGUI или Text в Canvas:
public Text scoreText;
void UpdateScoreUI()
{
scoreText.text = "Очки: " + score.ToString();
}
Сохранение данных: PlayerPrefs
Для простого сохранения без базы данных или внешнего файла используйте PlayerPrefs — встроенный механизм хранения значений типа int, float и string. Например, сохранить лучший результат:
PlayerPrefs.SetInt("BestScore", score);
Для загрузки значения при старте игры:
int bestScore = PlayerPrefs.GetInt("BestScore", 0);
Если хотите сбросить все сохранения — используйте PlayerPrefs.DeleteAll() (будьте осторожны, делайте это только при отладке).
Игровой цикл: допустим, игрок проиграл — как запустить игру заново?
using UnityEngine.SceneManagement;
public void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
Реализуйте это через кнопку в Canvas с событием OnClick, привязанным к методу RestartGame(). Это позволит возвращаться в игру после поражения без выхода в меню.
Меню «поражение»: Появление панели при проигрыше реализуем через активацию UI-объекта:
public GameObject gameOverPanel;
public void ShowGameOver()
{
gameOverPanel.SetActive(true);
}
Добавьте в сцену UI-Panel с надписью “Вы проиграли” и кнопками «Заново» и «Выход». Не забывайте отключить панель при запуске игры: gameOverPanel.SetActive(false);
Мини-цикл: игра-победа-переиграть: если вводите условия победы (например, собраны все монеты или достигнут выход), рекомендуется задать условие перехода на финальный экран:
if (score >= 100)
{
SceneManager.LoadScene("WinScene");
}
Создайте отдельную сцену WinScene с надписью «Поздравляем!» и вариантом переиграть.
Как понять, «игра работает»? Игровой цикл считается удовлетворительным, если:
- Игроку не скучно переиграть 3 раза подряд;
- Он запоминает правила без подсказок после 1 минуты;
- У него появляется челлендж «взять больше очков» или «пройти без урона»;
Интересный факт: по статистике Steam, менее 42% пользователей доходят до конца начальной миссии даже в популярных играх. Это значит — ваш геймплей должен цеплять не только механикой, но и отзывчивостью, предсказуемостью, простыми метриками прогресса (очки, очки жизни).
Сборка, публикуемая версия и что дальше
Вы разработали рабочий прототип. Что дальше? Показываем игру миру. Для этого она должна быть собрана в исполняемый файл под нужную платформу. Unity делает это просто: достаточно выбрать платформу и сделать экспорт. Но есть нюансы, которые важно не упустить.
Сборка игры: откройте File → Build Settings. Выберите нужную платформу:
- Windows — стабильный вариант для ПК;
- WebGL — позволяет размещать игру прямо в браузере;
- Android — требует установки Android Build Support;
Включите сцену в «Scenes In Build» (нажмите Add Open Scenes). Затем нажмите Build, выберите папку. Unity сгенерирует исполняемую версию игры (.exe или index.html, в зависимости от типа сборки).
Публикация:
- Itch.io — отлично подходит для прототипов; бесплатный, дружественный к инди-разработчикам. Поддерживает WebGL и загрузку .zip архивов;
- Google Play Console — идеальный старт для мобильной версии. Но потребует регистрации как разработчик (25 USD единоразово) и грамотной работы с Play Asset Delivery, если приложение требует более 100 Мб;
- Свой сайт — разместите игру как iframe WebGL-версии или выкладывайте сборку на облако (например, Dropbox) с прямой ссылкой на скачивание;
Что нельзя делать при публикации:
- Использовать чужую музыку, графику без лицензии — Google и Itch блокируют такие игры;
- Встраивать API или сервисы аналитики без политики конфиденциальности;
- Публиковать сборку с сообщениями Debug.Log в релизной версии — это влияет на производительность и лишний вес логов;
Как протестировать игру:
- Попросите 3–5 человек разного возраста пройти игру и записать, где они теряются;
- Следите за действиями: если игрок не находит кнопку старт или не понимает, как прыгать — это не его вина, а упущение UX;
- Составьте Google Form или Notion-таблицу с вопросами: “насколько сложно?”, “хочешь ли сыграть ещё?”, “что не понравилось?”;
Итерации — залог улучшения: первая версия редко бывает идеальной. Отзывы дают направление: кто-то хочет больше уровней, кто-то — другой стиль графики. Главное — не переоценить первое мнение, а собрать пул повторяющихся паттернов.
Что делать после публикации:
- Добавить уровень сложности;
- Добавить таймер или модификаторы;
- Интегрировать внутриигровую валюту (например, для продолжения после проигрыша);
- Улучшить анимацию или UI (например, анимированный счёт);
Вы довели игру до состояния, когда она живёт независимо и может путешествовать от компьютера к компьютеру. Потратьте время на качественную упаковку — это день, который отдастся высокой оценкой и интересом аудитории.
