5 проверенных способов реализации движения персонажа в Unity
Для кого эта статья:
- Начинающие разработчики игр в Unity
- Студенты игровых факультетов и курсов по программированию
Разработчики, ищущие советы по реализации движения персонажей в играх
Разработка в Unity часто начинается с главного вопроса: как заставить персонажа двигаться? Этот, казалось бы, простой аспект может стать настоящим камнем преткновения для начинающих разработчиков. Я помню свой первый проект, где мой герой либо взлетал в стратосферу, либо застревал в текстурах — знакомо? Сегодня я раскрою 5 проверенных способов реализации движения персонажа в Unity, от простейшего
transform.Translateдо продвинутых мобильных контроллеров. Каждый метод сопровождается рабочим кодом, который вы можете сразу использовать в своих проектах. 🚀
Хотите создавать потрясающие игры, но не знаете, с чего начать? Освойте не только Unity, но и основы веб-разработки с обучением веб-разработке от SkyPro. Эти навыки дополняют друг друга идеально — вы сможете не только программировать механики игры, но и создавать веб-версии ваших проектов, лендинги для продвижения игр и интегрировать онлайн-функционал. Комплексные знания современного разработчика в одном курсе!
Базовое движение персонажа в Unity: transform.Translate
Метод transform.Translate — это простейший способ заставить объект двигаться в Unity. Он идеален для новичков и прототипирования, поскольку не требует настройки физики или сложных компонентов. Это как первый автомобиль с механической коробкой передач — простой, но дающий полный контроль. 🚗
Антон Игнатьев, преподаватель игрового программирования
Когда я проводил свой первый геймдев-интенсив, студент пришел с "плавающим" персонажем — он постоянно проваливался сквозь пол и странно взаимодействовал с объектами. Оказалось, что он использовал
transform.Translateбез учета коллизий. Мы быстро переписали движение с базовой проверкой: "Если впереди стена — не двигайся". Игра сразу стала играбельной, хотя и не идеальной. Это отличный пример того, как даже простейшие решения могут работать при правильном применении.
Давайте рассмотрим простейший скрипт движения с использованием transform.Translate:
using UnityEngine;
public class SimpleMovement : MonoBehaviour
{
public float speed = 5f;
void Update()
{
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(horizontalInput, 0f, verticalInput);
// Перемещение объекта с учетом скорости и времени
transform.Translate(movement * speed * Time.deltaTime);
}
}
Этот скрипт считывает ввод с клавиатуры (WASD или стрелки) и преобразует его в перемещение. Важно использовать Time.deltaTime для обеспечения постоянной скорости независимо от частоты кадров.
Преимущества и недостатки transform.Translate:
| Преимущества | Недостатки |
|---|---|
| Простота использования | Не учитывает физику |
| Минимальное влияние на производительность | Может проходить сквозь коллайдеры |
| Предсказуемое поведение | Нет встроенной обработки столкновений |
| Подходит для 2D и 3D | Нереалистичное движение для некоторых игр |
Когда использовать transform.Translate:
- Для прототипирования игрового процесса
- В 2D-играх с простой механикой
- Для объектов, не требующих реалистичной физики
- В обучающих проектах и демонстрациях

Физическое движение с использованием Rigidbody
Когда ваша игра требует более реалистичной физики, на сцену выходит компонент Rigidbody. Он позволяет объектам подчиняться законам физики — гравитации, инерции, столкновениям. Представьте, что transform.Translate — это игрушечная машинка, которую вы толкаете рукой, а Rigidbody — полноценный автомобиль с двигателем и подвеской. 🏎️
Для использования Rigidbody необходимо:
- Добавить компонент
Rigidbodyк вашему объекту - Убедиться, что у объекта есть коллайдер
- Написать скрипт, использующий методы
Rigidbodyдля движения
Вот пример скрипта для управления персонажем с Rigidbody:
using UnityEngine;
public class RigidbodyMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public float jumpForce = 5f;
private Rigidbody rb;
private bool isGrounded;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
// Проверяем прыжок
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
isGrounded = false;
}
}
void FixedUpdate()
{
// Считываем ввод в FixedUpdate для физических расчетов
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(horizontalInput, 0f, verticalInput);
// Применяем силу для движения
rb.AddForce(movement * moveSpeed, ForceMode.Force);
// Ограничиваем скорость по горизонтали для лучшего контроля
Vector3 horizontalVelocity = new Vector3(rb.velocity.x, 0, rb.velocity.z);
if (horizontalVelocity.magnitude > moveSpeed)
{
horizontalVelocity = horizontalVelocity.normalized * moveSpeed;
rb.velocity = new Vector3(horizontalVelocity.x, rb.velocity.y, horizontalVelocity.z);
}
}
void OnCollisionEnter(Collision collision)
{
// Проверяем, стоит ли персонаж на земле
if (collision.contacts[0].normal.y > 0.5f)
{
isGrounded = true;
}
}
}
Обратите внимание на важные нюансы:
- Используйте FixedUpdate() для физических расчетов, а не
Update() AddForce()может применяться с разными режимами (Force, Impulse, Acceleration)- Для лучшего контроля часто требуется ограничение скорости
- Проверка заземления критична для прыжков
Михаил Резников, разработчик инди-игр
Разрабатывая платформер с использованием
Rigidbody, я столкнулся с проблемой — мой персонаж скользил по льду как по маслу и не мог остановиться. После часов отладки я понял: физический материал! Я настроил разныеPhysicMaterialдля разных поверхностей и добавил код для адаптации силы движения. Результат превзошел ожидания — персонаж теперь уверенно двигался по камню, слегка проскальзывал на металле и с трудом удерживался на льду. Из технической головоломки это превратилось в игровую механику, которую игроки оценили как одну из самых интересных в игре.
Управление персонажем через Character Controller
Character Controller — это специализированный компонент Unity, созданный специально для управления персонажами. Он сочетает в себе простоту transform.Translate с физическим взаимодействием Rigidbody, но без излишних сложностей. Это как внедорожник с автоматической коробкой передач — мощный, но простой в управлении. 🚙
Character Controller предоставляет методы для перемещения персонажа с учетом столкновений, позволяет настраивать параметры скольжения, определять заземление и многое другое.
Вот пример скрипта для 3D-платформера с использованием Character Controller:
using UnityEngine;
public class CharacterControllerMovement : MonoBehaviour
{
public float walkSpeed = 6.0f;
public float jumpSpeed = 8.0f;
public float gravity = 20.0f;
private CharacterController controller;
private Vector3 moveDirection = Vector3.zero;
void Start()
{
controller = GetComponent<CharacterController>();
}
void Update()
{
if (controller.isGrounded)
{
// Считываем ввод, если персонаж на земле
moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= walkSpeed;
// Прыжок
if (Input.GetButton("Jump"))
{
moveDirection.y = jumpSpeed;
}
}
// Применяем гравитацию
moveDirection.y -= gravity * Time.deltaTime;
// Перемещаем персонажа
controller.Move(moveDirection * Time.deltaTime);
}
}
Сравнение Character Controller с другими методами:
| Метод | Физика | Столкновения | Сложность | Контроль |
|---|---|---|---|---|
transform.Translate | Нет | Нет | Низкая | Высокий |
Rigidbody | Полная | Полные | Высокая | Низкий |
Character Controller | Частичная | Настраиваемые | Средняя | Средний |
Основные преимущества Character Controller:
- Интуитивно понятная обработка столкновений
- Встроенная проверка заземления (isGrounded)
- Настраиваемые параметры скольжения и восхождения по склонам
- Не подвержен неожиданным эффектам физического движка
- Оптимизирован для управления персонажами от первого и третьего лица
Character Controller идеально подходит для большинства 3D-игр с видом от первого или третьего лица, включая шутеры, RPG и приключенческие игры. 🎮
Движение персонажа с применением новой Input System
С релизом Unity 2019.1 разработчики получили доступ к новой Input System, которая заменяет традиционный способ обработки ввода. Новая система предлагает более гибкий, контекстно-зависимый подход к управлению и значительно упрощает работу с различными устройствами ввода. Это как переход с механической пишущей машинки на современную клавиатуру с настраиваемыми макросами. ⌨️
Для использования новой Input System необходимо:
- Установить пакет через
Package Manager(com.unity.inputsystem) - Создать файл
Input Action Asset - Настроить действия и привязки
- Использовать их в скриптах
Вот пример скрипта движения с использованием новой Input System:
using UnityEngine;
using UnityEngine.InputSystem;
public class InputSystemMovement : MonoBehaviour
{
public float moveSpeed = 5f;
public float jumpForce = 5f;
private CharacterController controller;
private Vector2 moveInput;
private Vector3 playerVelocity;
private bool jumpPressed;
private bool isGrounded;
private float gravity = -9.81f;
void Start()
{
controller = GetComponent<CharacterController>();
}
// Вызывается из Input Actions при перемещении
public void OnMove(InputValue value)
{
moveInput = value.Get<Vector2>();
}
// Вызывается из Input Actions при прыжке
public void OnJump(InputValue value)
{
jumpPressed = value.isPressed;
}
void Update()
{
isGrounded = controller.isGrounded;
if (isGrounded && playerVelocity.y < 0)
{
playerVelocity.y = -2f; // Небольшое значение для обеспечения заземления
}
Vector3 move = new Vector3(moveInput.x, 0, moveInput.y);
controller.Move(move * Time.deltaTime * moveSpeed);
// Поворачиваем персонажа в направлении движения
if (move != Vector3.zero)
{
transform.forward = move;
}
// Прыжок
if (jumpPressed && isGrounded)
{
playerVelocity.y += Mathf.Sqrt(jumpForce * -3.0f * gravity);
jumpPressed = false;
}
// Применяем гравитацию
playerVelocity.y += gravity * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
}
Ключевые преимущества новой Input System:
- Независимость от конкретных устройств ввода
- Поддержка событийной модели (callbacks)
- Возможность переназначения управления в рантайме
- Улучшенная поддержка геймпадов и других контроллеров
- Встроенная поддержка жестов для мобильных устройств
Новая Input System значительно упрощает реализацию кросс-платформенного управления, поскольку вы определяете абстрактные действия ("Move", "Jump"), а не конкретные клавиши или кнопки. Это позволяет игроку настраивать управление и легко поддерживать различные устройства ввода. 🎮🖱️📱
Реализация мобильного управления для персонажа в Unity
Создание управления для мобильных платформ требует особого подхода, так как здесь нет физических кнопок, а взаимодействие происходит через сенсорный экран. Разработка мобильного управления в Unity — это как проектирование автомобиля с сенсорной панелью вместо руля и педалей. 📱
Существует несколько популярных методов управления персонажем на мобильных устройствах:
- Виртуальные джойстики
- Экранные кнопки
- Свайпы и жесты
- Наклон устройства (акселерометр)
Рассмотрим пример реализации виртуального джойстика — наиболее универсального и интуитивно понятного метода:
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class TouchJoystick : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
[SerializeField] private RectTransform joystickBackground;
[SerializeField] private RectTransform joystickHandle;
[SerializeField] private float joystickRange = 50f;
private Vector2 inputDirection;
private bool isTouching = false;
public Vector2 InputDirection => inputDirection;
public bool IsTouching => isTouching;
public void OnDrag(PointerEventData eventData)
{
Vector2 position = RectTransformUtility.WorldToScreenPoint(null, joystickBackground.position);
Vector2 radius = joystickBackground.sizeDelta / 2;
// Рассчитываем направление от центра джойстика к точке касания
inputDirection = (eventData.position – position) / (radius * joystickRange);
// Ограничиваем величину вектора до 1 для нормализации
if (inputDirection.magnitude > 1)
inputDirection.Normalize();
// Перемещаем рукоять джойстика
joystickHandle.anchoredPosition = inputDirection * radius * joystickRange;
}
public void OnPointerDown(PointerEventData eventData)
{
isTouching = true;
OnDrag(eventData);
}
public void OnPointerUp(PointerEventData eventData)
{
isTouching = false;
inputDirection = Vector2.zero;
joystickHandle.anchoredPosition = Vector2.zero;
}
}
А вот как использовать этот джойстик для управления персонажем:
using UnityEngine;
public class MobileCharacterController : MonoBehaviour
{
[SerializeField] private TouchJoystick moveJoystick;
[SerializeField] private Button jumpButton;
[SerializeField] private float moveSpeed = 5f;
[SerializeField] private float rotationSpeed = 10f;
private CharacterController controller;
private Vector3 playerVelocity;
private bool isGrounded;
private float gravity = -9.81f;
void Start()
{
controller = GetComponent<CharacterController>();
// Настройка кнопки прыжка
jumpButton.onClick.AddListener(OnJump);
}
void OnJump()
{
if (isGrounded)
{
playerVelocity.y = Mathf.Sqrt(3f * -gravity);
}
}
void Update()
{
isGrounded = controller.isGrounded;
if (isGrounded && playerVelocity.y < 0)
{
playerVelocity.y = -2f;
}
// Получаем ввод с джойстика
Vector2 joystickInput = moveJoystick.InputDirection;
// Преобразуем 2D ввод в 3D движение
Vector3 move = new Vector3(joystickInput.x, 0, joystickInput.y);
// Перемещаем персонажа
controller.Move(move * moveSpeed * Time.deltaTime);
// Поворачиваем персонажа в направлении движения
if (move != Vector3.zero)
{
Quaternion targetRotation = Quaternion.LookRotation(move);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
}
// Применяем гравитацию
playerVelocity.y += gravity * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
}
Советы по оптимизации мобильного управления:
- Размещайте элементы управления в легкодоступных зонах экрана
- Делайте сенсорные области достаточно большими
- Добавьте настройку чувствительности
- Предусмотрите альтернативные схемы управления
- Добавьте тактильную отдачу (вибрацию) для подтверждения действий
При разработке мобильных игр также стоит учитывать разнообразие размеров экранов и адаптировать интерфейс управления с помощью Canvas Scaler. Не забывайте тестировать на разных устройствах — что удобно на большом планшете, может быть неиграбельно на компактном смартфоне. 📊
Реализация движения персонажа — это фундамент любой игры в Unity. Мы рассмотрели пять различных подходов: от простейшего
transform.Translateдо сложных мобильных контроллеров. Каждый метод имеет свои преимущества в зависимости от типа вашей игры.Transform.Translateидеален для прототипирования,Rigidbodyдаёт реалистичную физику,Character Controllerупрощает 3D-платформеры, новаяInput Systemобеспечивает кросс-платформенность, а мобильное управление открывает доступ к огромной аудитории смартфонов. Не бойтесь экспериментировать и комбинировать эти техники — именно так рождаются уникальные игровые механики!
Читайте также
- Unity: как создать и опубликовать игру в App Store и Google Play
- Frustum Culling в Unity: оптимизация рендеринга игровых сцен
- Продвинутые методы интерполяции в Unity: плавное перемещение объектов
- Где искать информацию по Unity: путеводитель разработчика
- Основы программирования на C# для начинающих разработчиков Unity
- Оптимизация Unity: инструменты и методы для плавного геймплея
- Как повысить FPS в Unity: эффективная оптимизация с Batching
- Project Settings в Unity: полная настройка и оптимизация проекта
- Как добавить ассеты в Unity: пошаговое руководство для новичков
- Как заставить объекты вращаться в Unity: практическое руководство