Новый Input System: чтение управления

Управление — это связь игрока с игрой. В Unity 6 для него есть новый Input System, который из коробки понимает клавиатуру, мышь и геймпад.

Суть: в Unity 6 новый Input System включён по умолчанию. Вместо проверки конкретных клавиш ты описываешь действия (Move, Jump, Fire) и привязки к ним (клавиши, кнопки геймпада). Код реагирует на действие, а не на конкретную кнопку — это абстракция ввода.

Раньше в Unity ввод читали напрямую: «нажат ли пробел?». Это работало, но плохо масштабировалось: добавить геймпад или переназначить клавиши было больно. Новый Input System вводит слой абстракции: ты описываешь действие «Прыжок», а к нему привязываешь и пробел, и кнопку A на геймпаде. Код спрашивает «выполнено ли действие Прыжок?», не зная, чем именно.

В Unity 6 новый Input System поставляется с готовым набором действий и включён по умолчанию — старт стал намного дружелюбнее. Действия хранятся в ассете Input Actions, где их удобно настраивать визуально.

Как работает под капотом

Слой абстракции ввода:

  Устройства           Действия            Игровая логика
  ----------           --------            --------------
  Пробел (клавиша) --\
  Кнопка A (пад)   ----+--> "Jump"   -->   прыжок героя
  Стрелки          --\
  Левый стик (пад) ----+--> "Move"   -->   движение героя

Логика знает про "Jump"/"Move", а не про конкретные кнопки.

Прелесть в том, что переназначение клавиш или поддержка нового геймпада не трогают игровую логику — меняются только привязки. Это и есть смысл абстракции.

using UnityEngine;
using UnityEngine.InputSystem;   // новый Input System

public class PlayerInputReader : MonoBehaviour
{
    private Vector2 moveInput;

    // Вызывается системой ввода при действии "Move"
    public void OnMove(InputAction.CallbackContext ctx)
    {
        moveInput = ctx.ReadValue<Vector2>();
    }

    public void OnJump(InputAction.CallbackContext ctx)
    {
        if (ctx.performed) Debug.Log("Прыжок!");
    }
}

Смоделируем слой абстракции ввода на Python — карта «действие → клавиши» и опрос действия:

# Действие -> список устройств/кнопок, которые его вызывают
bindings = {
    "Jump": ["Space", "GamepadA"],
    "Move": ["Arrows", "LeftStick"],
}

# Что сейчас зажато игроком (любое устройство)
pressed = {"GamepadA"}

def is_action(action):
    return any(key in pressed for key in bindings[action])

print("Jump активен?", is_action("Jump"))   # да: нажата кнопка геймпада
print("Move активен?", is_action("Move"))   # нет

# Переназначили прыжок на другую клавишу — логика не меняется
bindings["Jump"].append("Enter")
pressed = {"Enter"}
print("Jump после переназначения:", is_action("Jump"))

Та же логика на Python ▶ — логика спрашивает «активно ли действие Jump?», а какие именно кнопки за ним стоят — дело настроек. Поэтому добавление геймпада или ремап клавиш не трогает геймплейный код.

Частые ошибки

  • Мешать старый и новый ввод. Если в настройках выбран только новый Input System, старый Input.GetKey перестанет работать и кинет ошибку. Выбери один подход.
  • Читать непрерывный ввод как разовый. Движение (Move) — это значение каждый кадр, прыжок (Jump) — разовое событие. Путаница даёт «залипание».
  • Жёстко зашивать клавиши в логику. Это убивает главное преимущество системы — переназначение и геймпады.

Best practices

  • Описывай ввод действиями (Move, Jump, Fire), а не клавишами — так игра сразу дружит с геймпадом.
  • Непрерывные действия (движение) читай как значение в Update; разовые (прыжок, выстрел) — по событию performed.
  • Дай игроку возможность переназначать управление — Input System это умеет почти бесплатно.

Итоги: новый Input System (по умолчанию в Unity 6) вводит слой абстракции: устройства → действия → логика. Код реагирует на действия (Move, Jump), а не на конкретные кнопки. Это даёт поддержку геймпадов и переназначение клавиш без правки геймплея. Не мешай старый и новый ввод в одном проекте.

Action Maps: разный ввод в разных режимах

Игра редко читает ввод одинаково всё время. В меню стрелки листают пункты, в бою — двигают героя, в режиме диалога — мотают текст. Новый Input System решает это через Action Maps — наборы действий, которые можно включать и выключать целиком. Карта Gameplay активна во время игры, карта UI — в меню; переключил карту, и одни и те же кнопки начали означать другое, без единого if про «а мы сейчас в меню?». Это куда чище, чем разводить режимы флагами в коде. Плюс система из коробки умеет вещи, которые раньше писали руками: мёртвые зоны стиков, обработку одновременного нажатия, удержание против короткого тапа. Поэтому даже для маленькой игры новый Input System окупается — он берёт на себя скучную и ошибкоопасную часть работы с устройствами.

Проверьте себя
1. В чём главная идея нового Input System?
AОн быстрее рисует
BКод реагирует на действия (Jump, Move), а не на конкретные клавиши
CОн работает без камеры
DОн заменяет физику
2. Что будет, если в проекте выбран только новый Input System, а код использует старый Input.GetKey?
AВсё работает как раньше
BСтарый вызов перестанет работать и кинет ошибку
CИгра станет быстрее
DНичего не изменится