~2 мин чтения

Ввод — Input System и legacy Input

Клавиатура, мышь, геймпад и тач — два пути и почему стоит идти новым.

В Unity сейчас сосуществуют две системы ввода. Legacy Input класс — старый и простой. Input System package — новый, мощный и рекомендованный для новых проектов.

Legacy Input — быстрый старт

Класс Input доступен из коробки. Опрашивается каждый кадр в Update:

private void Update() {
    float h = Input.GetAxis("Horizontal"); // -1..1, левый стик/A-D/стрелки
    float v = Input.GetAxis("Vertical");

    if (Input.GetButtonDown("Jump")) {
        // пробел был нажат в этом кадре
    }

    if (Input.GetMouseButton(0)) {
        // ЛКМ удерживается
    }

    Vector2 mouseDelta = new Vector2(
        Input.GetAxis("Mouse X"),
        Input.GetAxis("Mouse Y")
    );
}

Кнопки и оси определяются в Edit → Project Settings → Input Manager. Это словарь со значениями по умолчанию: “Horizontal”, “Vertical”, “Jump”, “Fire1”, “Mouse X” и так далее.

Legacy Input — deprecated с Unity 6.3

В Unity 6.3 LTS legacy Input Manager официально помечен deprecated с предупреждением в редакторе. API ещё работает, но удалят в одной из будущих major-версий. Используйте legacy только для быстрых прототипов или поддержки старых проектов. В новом коде — Input System.

Input System — современный путь

Input System — это пакет (устанавливается через Package Manager). Главные идеи:

  1. Actions, а не клавиши. Вы описываете действия (“Move”, “Jump”, “Shoot”) и привязываете к ним физические кнопки/оси/жесты. Один action — много привязок.
  2. Композитные привязки. “WASD” = композит из 4 клавиш, который возвращает Vector2.
  3. Контрольные схемы. “Keyboard & Mouse” vs “Gamepad” — автоматическое переключение, разные привязки.
  4. Callbacks, не polling. Подписываетесь на performed, started, canceled.

Action Asset

В Project — Create → Input Actions. Открывается визуальный редактор: создаёте Action Map (например, “Player”), внутри — actions, и для каждого — bindings.

После настройки Unity сгенерирует C# класс (через “Generate C# Class” в инспекторе), которым удобно пользоваться:

using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    private PlayerControls _controls; // сгенерированный класс

    private Vector2 _moveInput;

    private void Awake() {
        _controls = new PlayerControls();
        _controls.Player.Move.performed   += ctx => _moveInput = ctx.ReadValue<Vector2>();
        _controls.Player.Move.canceled    += _   => _moveInput = Vector2.zero;
        _controls.Player.Jump.performed   += _   => TryJump();
    }

    private void OnEnable()  => _controls.Enable();
    private void OnDisable() => _controls.Disable();

    private void Update() {
        var move = new Vector3(_moveInput.x, 0, _moveInput.y);
        transform.Translate(move * 5f * Time.deltaTime, Space.Self);
    }

    private void TryJump() { /* ... */ }
}
PlayerInput компонент

Можно обойтись без ручного кода: вешаете компонент PlayerInput на GameObject, указываете Action Asset, и связываете actions с вашими методами через UnityEvents в Inspector. Хорошо для прототипов и кооперативной локалки (легко привязать второго игрока к второму геймпаду).

Поворот камеры мышью

Классическая задача: повернуть голову игрока за курсором. Pattern с Input System:

public class MouseLook : MonoBehaviour
{
    [SerializeField] private float sensitivity = 0.1f;
    [SerializeField] private Transform cameraPivot;

    private float _pitch;
    private float _yaw;
    private Vector2 _lookInput;

    private void Awake() {
        Cursor.lockState = CursorLockMode.Locked; // спрятать и заблокировать
        Cursor.visible = false;
    }

    public void OnLook(InputAction.CallbackContext ctx) {
        _lookInput = ctx.ReadValue<Vector2>();
    }

    private void Update() {
        _yaw   += _lookInput.x * sensitivity;
        _pitch -= _lookInput.y * sensitivity;
        _pitch = Mathf.Clamp(_pitch, -85f, 85f);

        transform.localRotation = Quaternion.Euler(0, _yaw, 0);
        cameraPivot.localRotation = Quaternion.Euler(_pitch, 0, 0);
    }
}

Важная деталь: pitch (вертикаль) применяется к дочернему объекту-камере, yaw (горизонталь) — к телу игрока. Это разделение упрощает физику: коллайдер игрока не наклоняется при взгляде вверх-вниз.

Geometry Raycast: “куда смотрит игрок”

Стрельба, выбор предмета, click-to-move — всё это построено на raycast. Луч из точки в направлении, ищет первое пересечение с коллайдером:

private void Shoot() {
    var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    if (Physics.Raycast(ray, out RaycastHit hit, maxDistance: 100f)) {
        Debug.Log($"Попали в {hit.collider.name} на расстоянии {hit.distance:F2}");
        if (hit.collider.TryGetComponent<Enemy>(out var enemy)) {
            enemy.TakeDamage(10);
        }
    }
}

Camera.main.ScreenPointToRay — стандартный приём перевести позицию курсора в луч из камеры. Для FPS можно проще: transform.forward от камеры.

В следующем разделе — физика: как Rigidbody и Collider взаимодействуют между собой и с вашими скриптами.