Привет! В этом туториале мы вместе создадим простой 2D платформер на движке Unity. Тебе не нужно быть экспертом — мы всё объясним понятно и пошагово. Мы будем использовать встроенную физику 2D и немного коснёмся анимации (привет, спрайт-листы!). Чтобы пройти урок, тебе понадобятся некоторые ресурсы: изображения, звуки и не только. Скачать архив .zip можно здесь — в нём есть всё, что нужно для старта.
Запусти Unity и создай новый 2D-проект. Сначала мы сделаем основу игры: объект земли и персонажа.
Сначала импортируй largeGround
из архива (если нужно — скачать здесь). Распакуй .zip и перетащи largeGround
в сцену.
Переименуй созданный GameObject в Ground.
Выбери Ground в иерархии. В инспекторе:
0
.
Теперь добавим игрока. Импортируй спрайт-лист ratIdle
(он тоже в архиве). Unity, скорее всего, автоматически нарежет его.
Если нет — сделай так:
ratIdle
в папке Assets.Multiple
.
4
, Ряды: 5
, и нажми
Slice.
Разверни спрайт-лист — теперь в нём должно быть 20 кадров. Перетащи первый кадр в сцену. Переименуй созданный GameObject в Rat.
Выбери объект Rat и сделай следующие настройки:
Player
.0
.Interpolate
.
Пора заставить нашу крыску двигаться! Создадим скрипт, который будет отвечать и за бег, и за прыжки.
В папке Assets кликни правой кнопкой мыши и выбери
создание нового C#-скрипта. Назови его PlayerMove
. Этот
скрипт будет использовать компонент Rigidbody2D для
перемещения игрока с помощью встроенной физики Unity. Мы также добавим
прыжок, применяя силу вверх по оси Y.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
// Какие слои считаются "землёй" (задать в Инспекторе)
public LayerMask whatIsGround;
// Точка, по которой проверяется, стоит ли игрок на земле
public Transform groundCheck;
// Находится ли игрок сейчас на земле?
public bool isGrounded;
// Сила прыжка
public float jumpForce;
// Скорость движения влево/вправо
public float speed;
// Ссылка на компонент Rigidbody2D
Rigidbody2D rb;
void Start()
{
// Получаем компонент Rigidbody2D, прикреплённый к объекту
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// Если нажата кнопка прыжка и игрок стоит на земле
if (Input.GetButtonDown("Jump") && isGrounded)
{
// Добавляем силу вверх для прыжка
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
// Запрещаем повторный прыжок — сбросится в FixedUpdate
isGrounded = false;
}
}
void FixedUpdate()
{
// Проверяем, касается ли точка GroundCheck слоя "земля"
isGrounded = Physics2D.OverlapPoint(groundCheck.position, whatIsGround);
// Получаем горизонтальный ввод (стрелки или A/D)
float x = Input.GetAxis("Horizontal");
// Создаём вектор движения (сохраняем вертикальную скорость)
Vector3 move = new Vector3(x * speed, rb.linearVelocity.y, 0f);
// Применяем движение к Rigidbody
rb.linearVelocity = move;
}
}
Прикрепи скрипт PlayerMove
к объекту
Rat. В инспекторе установи Speed на
3
и Jump Force на 5
.
Теперь создадим вспомогательный объект для определения земли. Кликни
правой кнопкой на
Rat в иерархии → Create Empty, переименуй
его в GroundCheck
и перемести чуть ниже лапок крысы (но
вне её коллайдера).
Чтобы прыжки работали, нужно ещё указать, что такое “земля”. Выдели
объект Ground и задай ему Layer как
Ground
. Если слоя с таким названием нет — создай его.
Теперь снова выбери Rat. В компоненте PlayerMove:
Ground Check
.
What Is Ground
выбери слой Ground
.
💡 Совет: Если слой Ground
не
отображается в списке, убедись, что ты выделил объект земли и добавил
нужный слой.
Нажми Play — теперь крыса должна двигаться влево и вправо (с помощью стрелок или A/D) и прыгать, когда стоит на земле.
Крыса теперь умеет двигаться и прыгать — но всё время смотрит в одну сторону. Давай научим её разворачиваться в сторону движения. Для этого мы добавим новую переменную в скрипт и напишем функцию, которая будет "отражать" спрайт при смене направления.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : MonoBehaviour
{
// Какие слои считаются "землёй" (указать в инспекторе)
public LayerMask whatIsGround;
// Точка, по которой проверяется, стоит ли игрок на земле
public Transform groundCheck;
// Стоит ли игрок сейчас на земле?
public bool isGrounded;
// Сила прыжка
public float jumpForce;
// Скорость движения влево/вправо
public float speed;
// Ссылка на компонент Rigidbody2D
Rigidbody2D rb;
// Указывает, смотрит ли крыса влево (true = влево)
public bool isLookingLeft;
void Start()
{
// Получаем компонент Rigidbody2D, прикреплённый к объекту
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// Если нажата кнопка прыжка и крыса на земле
if (Input.GetButtonDown("Jump") && isGrounded)
{
// Прыгаем вверх с заданной силой
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
// Запрещаем двойной прыжок — флаг сбросится в FixedUpdate
isGrounded = false;
}
}
void FixedUpdate()
{
// Проверка: GroundCheck касается слоя земли?
isGrounded = Physics2D.OverlapPoint(groundCheck.position, whatIsGround);
// Получаем ввод по горизонтали (стрелки или A/D)
float x = Input.GetAxis("Horizontal");
// Создаём вектор движения (сохраняем вертикальную скорость)
Vector3 move = new Vector3(x * speed, rb.linearVelocity.y, 0f);
// Применяем движение
rb.linearVelocity = move;
// Если идём влево и ещё не повернуты влево — поворачиваемся
if (x < 0 && !isLookingLeft)
TurnTheRat();
// Если идём вправо, а смотрим влево — тоже поворачиваемся
if (x > 0 && isLookingLeft)
TurnTheRat();
}
// Поворачивает крысу, инвертируя масштаб по оси X
void TurnTheRat()
{
// Меняем флаг направления
isLookingLeft = !isLookingLeft;
// Зеркально отражаем спрайт
transform.localScale = new Vector3(
transform.localScale.x * -1,
transform.localScale.y,
transform.localScale.z
);
}
}
Выдели объект Rat в иерархии. В компоненте
PlayerMove поставь галочку
Is Looking Left
— она должна соответствовать исходному
направлению спрайта (если твоя крыса изначально смотрит влево).
Готово! Теперь крыса бегает, прыгает и смотрит в ту сторону, куда движется. Маленькая деталь, но она добавляет жизни всей сцене.
Начнём анимировать нашу крысу! Для начала добавим компонент Animator и создадим контроллер.
В иерархии выбери GameObject Rat. В инспекторе нажми Add Component и выбери Animator.
Затем в окне Assets кликни правой кнопкой и создай
новый Animator Controller. Назови его
RatAnimator
.
Теперь присвой контроллер RatAnimator
полю
Controller в компоненте Animator у объекта
Rat.
Давай оживим крысу с помощью её первой анимации — петли ожидания (idle loop).
Открой окно Animation, если оно ещё не видно. Можно включить его через Window → Animation → Animation и закрепить где тебе удобно (я, например, размещаю его над окном Assets).
Выбери объект Rat в иерархии. В окне Animation нажми
Create и сохрани новую анимацию с именем
IdleRatAnimation
.
Теперь добавим кадры из спрайт-листа. В окне
Assets разверни ratIdle
. Выдели все 20
кадров: кликни по первому, затем удерживай Shift и
кликни по последнему. Перетащи выделенные кадры на временную шкалу
(timeline) в окне Animation.
Открой окно Animator (через Window → Animation →
Animator), если оно ещё не открыто. Дважды кликни по состоянию
IdleRatAnimation
— или просто выбери его в Assets.
В панели Inspector убедись, что включён параметр
Loop Time (цикличное воспроизведение). Можно также
настроить Speed — например, поставить
0.5
, чтобы анимация выглядела более плавной.
Пора анимировать движение крысы! Давай создадим анимацию бега и настроим переходы между состояниями.
Сначала импортируй спрайт ratRun
из архива в папку
Assets.
Выдели объект Rat в иерархии. В окне
Animation нажми на выпадающий список рядом с
IdleRatAnimation
и выбери
Create New Clip. Назови новую анимацию
RunRatAnimation
.
(Убедись, что объект Rat выбран в иерархии — иначе Unity не даст
добавить новую анимацию.)
В окне Assets разверни ratRun
и выдели все 20 кадров:
кликни по первому, зажми Shift и кликни по
последнему. Перетащи все выделенные кадры в окно
Animation, чтобы заполнить временную шкалу.
Открой окно Animator. Если его не видно — включи через Window → Animation → Animator.
По умолчанию, IdleRatAnimation
— начальное состояние. Мы
создадим параметр типа Float, чтобы управлять
переходами между ожиданием и бегом.
Speed
.
IdleRatAnimation
→
Make Transition → выбери
RunRatAnimation
.
RunRatAnimation
к
IdleRatAnimation
.
Теперь настроим сами переходы:
IdleRatAnimation → RunRatAnimation
.
Speed
должен быть Greater than
0.01
.
RunRatAnimation → IdleRatAnimation
.
Speed
Less than
0.01
.
Чтобы управлять переходами между анимациями, мы создадим простой
скрипт, который будет передавать информацию о движении в Animator. Он
будет переключаться между Idle
и Run
в
зависимости от скорости крысы.
В папке Assets создай новый C#-скрипт и назови его
PlayerAnim
. Затем вставь следующий код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAnim : MonoBehaviour
{
// Ссылка на Animator
Animator anim;
// Ссылка на Rigidbody2D
Rigidbody2D rb;
void Start()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// Обновляем параметр Speed в Animator (по абсолютному значению горизонтальной скорости)
anim.SetFloat("Speed", Mathf.Abs(rb.linearVelocity.x));
}
}
Прикрепи скрипт PlayerAnim
к объекту
Rat.
Готово! Теперь при запуске сцены крыса будет автоматически переключаться между анимациями ожидания и бега в зависимости от своего движения.
Давай создадим анимацию прыжка для нашей крысы. У нас нет отдельного
спрайта для прыжка, но мы можем повторно использовать
ratRun
с уменьшенной скоростью — получится эффект прыжка.
Выдели объект Rat в иерархии. В окне
Animation нажми на выпадающий список и выбери
Create New Clip. Назови новую анимацию
JumpRatAnimation
.
В Assets разверни спрайт-лист ratRun
. Выдели все 20
кадров (первый → Shift → последний), затем перетащи
их в таймлайн окна Animation.
Открой окно Animator. Сейчас мы добавим параметр и свяжем его с логикой прыжка.
isJumping
.
JumpRatAnimation
.
JumpRatAnimation
к
IdleRatAnimation
.
Настроим переходы следующим образом:
isJumping == true
.isJumping == false
.
Наконец, выдели состояние JumpRatAnimation
и установи
Speed на 0.2
, чтобы бег выглядел как
прыжок.
Теперь свяжем анимацию прыжка с фактическим состоянием крысы. Для
этого мы получим доступ к переменной isGrounded
из
скрипта PlayerMove
. Если крыса не на земле (включая
падение), будет запускаться анимация прыжка.
Открой скрипт PlayerAnim
и замени содержимое на
следующее:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerAnim : MonoBehaviour
{
// Ссылка на компонент Animator
Animator anim;
// Ссылка на Rigidbody2D
Rigidbody2D rb;
// Ссылка на скрипт PlayerMove (для доступа к isGrounded)
PlayerMove pm;
void Start()
{
// Получаем компонент Animator с этого объекта
anim = GetComponent<Animator>();
// Получаем компонент Rigidbody2D
rb = GetComponent<Rigidbody2D>();
// Получаем скрипт PlayerMove
pm = GetComponent<PlayerMove>();
}
void Update()
{
// Если крыса стоит на земле
if (pm.isGrounded)
{
// Прыжок завершён
anim.SetBool("isJumping", false);
// Обновляем Speed на основе горизонтального движения
anim.SetFloat("Speed", Mathf.Abs(rb.linearVelocity.x));
}
else
{
// Во время прыжка или падения скорость ставим в 0
anim.SetFloat("Speed", 0);
// Включаем анимацию прыжка
anim.SetBool("isJumping", true);
}
}
}
И всё! Больше ничего настраивать не нужно. Теперь анимация прыжка будет включаться автоматически, как только крыса окажется в воздухе — прыгая вверх или падая вниз.
Добавим немного жизни крысе — она будет издавать звуки шагов во время бега. Мы реализуем это с помощью события в анимации, которое вызовет функцию из нового скрипта.
В папке Assets создай новый C#-скрипт и назови его
PlayerSound
. Вставь в него следующий код:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerSound : MonoBehaviour
{
// Аудиоклип со звуком шагов
public AudioClip footsteps;
// Публичная функция для воспроизведения звука — вызывается из анимации
public void FootStepsAudio()
{
// Воспроизводим звук в позиции крысы
AudioSource.PlayClipAtPoint(footsteps, transform.position);
}
}
Выбери объект Rat в иерархии и добавь к нему скрипт
PlayerSound
. Затем импортируй звук
ratStep
из архива и назначь его в поле
Footsteps
компонента.
Теперь открой окно Animation и выбери
RunRatAnimation
. Найди подходящий кадр, где происходит
шаг, и нажми Add Event на таймлайне. В панели
Inspector (справа) укажи имя функции
FootStepsAudio()
.
Готово! Теперь, когда крыса дойдёт до нужного кадра во время бега, она издаст звук шага. Можно добавить несколько таких событий, чтобы синхронизировать их с каждым шагом.
Давай немного расширим уровень и настроим камеру, чтобы она следовала за крысой. Так у нас появится больше пространства для тестирования и подготовки к следующей части.
Сначала преврати исходный объект земли в префаб. Выдели Ground в иерархии и перетащи его в папку Assets, чтобы создать префаб.
Теперь перетащи этот префаб обратно в сцену несколько раз, чтобы создать дополнительные платформы. Расположи их на разных горизонтальных (и при желании — вертикальных) уровнях, чтобы добавить немного прыжкового вызова.
Затем выбери Main Camera в иерархии и перетащи её внутрь объекта Rat. Теперь камера станет дочерним объектом крысы и будет следовать за ней при движении.
При желании можешь установить позицию X у камеры в 0
в
инспекторе Transform — это сделает перемещение более плавным и
аккуратным при разворотах.
И вот и всё — первая часть завершена! Теперь у тебя есть живая крыса, которая умеет двигаться, прыгать, анимироваться, издавать шаги и гулять по расширенному уровню с камерой-наблюдателем.