Перейти к содержанию

Ввод и взаимодействие

Система ввода разделяет обнаружение ввода (мышь, клавиатура, геймпад и legacy navigation axes) и действия (перетаскивание, выделение, контекстное меню). Это позволяет менять привязки без переписывания логики и поддерживать разные устройства ввода.


Как устроен ввод

flowchart LR
    A["Мышь /\nКлавиатура /\nГеймпад"] --> B["Определение\nрежима ввода"]
    B --> C["Распознавание\nжеста"]
    C --> D{"Какое\nдействие?"}
    D --> E["Перетаскивание"]
    D --> F["Контекстное меню"]
    D --> G["Выделение"]
    D --> H["Автоперенос"]

Слот сам не знает, что делать с вводом. Он пересылает сырые события (нажатие, отпускание, наведение) в InputEventRouter, который ищет подходящую привязку и выполняет действие.


Фазы нажатия

Система различает несколько типов нажатия по длительности и перемещению курсора:

flowchart TD
    A["Нажатие"] --> B{"Что произошло дальше?"}
    B -->|"Отпустили быстро\nи курсор не двигался"| C["Быстрый клик"]
    B -->|"Держали дольше порога\n0.35 сек"| D["Долгое нажатие"]
    B -->|"Курсор сдвинулся\nбольше 8 px"| E["Перетаскивание"]
Фаза Условие Типичное действие
ClickShort Быстро нажали и отпустили, курсор не сдвинулся Автоперенос, выделение
ClickLong Держали дольше порога, курсор не сдвинулся Контекстное меню
Down Момент нажатия Начало перетаскивания
Up Момент отпускания Завершение перетаскивания

Пороги настраиваются в InputEventRouter: _longClickThresholdSeconds (по умолчанию 0.35 сек) и _clickMoveTolerancePixels (по умолчанию 8 пикселей).


Профили привязок

Привязки настраиваются через ScriptableObject InteractionBindingsProfile. В нём есть pointer bindings, legacy KeyCode bindings, legacy Input Manager bindings по имени кнопки и опциональные Input Action bindings.

Привязки указателя (Pointer Bindings)

Каждая привязка состоит из: кнопка мыши + модификатор + фаза + действие.

Кнопка Модификатор Фаза Действие
ЛКМ --- ClickShort Автоперенос
ЛКМ --- Down Начать перетаскивание
ЛКМ --- Up Завершить перетаскивание
ЛКМ Ctrl ClickShort Переключить выделение
ЛКМ Shift ClickShort Диапазонное выделение
ПКМ --- ClickShort Контекстное меню

Привязки Legacy Input Manager

Используйте LegacyInputActionBinding, если проект всё ещё работает через старый Input Manager и действие нужно задавать строковым именем кнопки, а не KeyCode. Типичные имена: Submit, Cancel или любая своя кнопка из Project Settings > Input Manager.

Имя кнопки Фаза Типичное действие
Submit Down Автоперенос или завершение drag
Cancel Down Отмена drag или закрытие UI

Эти привязки опрашиваются через InputEventRouter и требуют включённой поддержки Legacy Input Manager в Player Settings. Они не заменяют InputActionBinding: это отдельный путь для старой системы ввода.

Привязки Input Action

Для опциональных hotkeys и gamepad-специфичных сценариев: привязка Input System Action к действию инвентаря. Mixed setup поддерживается, но важно помнить, что InputAction-зависимые функции всё равно ожидают, что для этой сцены/flow настроен новый input pipeline. Если сцена намеренно остаётся на StandaloneInputModule, pointer и navigation там могут работать, а часть InputAction-функций — нет.


Режим ввода

Система автоматически определяет текущий режим ввода:

Режим Как активируется Поведение
Mouse Клик мышью или движение мыши Фокус через наведение, стандартные события указателя
Navigation Стрелки, WASD, Submit/Cancel, Tab, D-pad геймпада Фокус через EventSystem.selectedGameObject, навигация между слотами

Переключение происходит автоматически и в legacy input, и в новом Input System. Когда активен режим Navigation, InputEventRouter поддерживает фокус на слоте --- если текущий выделенный объект стал неактивным, система находит ближайший доступный слот.


Переопределение привязок для инвентаря

Каждый инвентарь может иметь свои привязки через компонент InventoryExtraInteractionBinder. Это полезно, когда у торговца и у игрока разное поведение по клику.

Если на инвентаре нет InventoryExtraInteractionBinder, используется дефолтный InteractionBindingsProfile из InputEventRouter.


Частичный сброс (Split Drop)

При перетаскивании стека можно сбросить часть предметов в слот, не прекращая перетаскивание. Остаток остаётся "в руке", визуал и счётчик обновляются автоматически.

Для этого используется встроенное действие SplitDropAction:

Параметр Описание По умолчанию
_splitCount Сколько предметов отщеплять за раз 1
_dropPolicyOverride Переопределение drop policy для этой операции ---

Настройка привязки

Добавьте PointerBinding в InteractionBindingsProfile:

Кнопка Модификатор Фаза Действие
ЛКМ Shift Down SplitDropAction

Порядок привязок

Привязка Shift + ЛКМ должна стоять выше обычной привязки ЛКМ (Start/Complete drag), чтобы модификатор матчился первым.

Как работает

  1. Игрок берёт стек из 10 предметов (обычный drag).
  2. Зажимает Shift и кликает по пустому слоту.
  3. 1 предмет переносится через стандартный конвейер (движок переноса → события).
  4. Перетаскивание продолжается с 9 предметами, визуал обновляется.
  5. Когда в стеке остаётся 1 предмет, Shift+Click выполняет обычный CompleteDrag.

Если целевой слот занят и не может принять предмет, операция откатывается — стек остаётся без изменений.


Справочник классов

Класс Роль
InputEventRouter Синглтон: маршрутизирует ввод к привязкам
InteractionBindingsProfile SO-профиль с pointer, legacy и Input Action привязками
SlotInputAdapter Компонент на слоте: пересылает сырые события
InputModalityTracker Определяет текущий режим ввода (Mouse / Navigation) и в legacy, и в Input System конфигурации
PointerBinding Привязка: кнопка + модификатор + фаза + действие
KeyBinding Legacy KeyCode привязка к действию
LegacyInputActionBinding Привязка старого Input Manager по имени кнопки к действию
InputActionBinding Привязка Input System Action к действию
InventoryExtraInteractionBinder Переопределение привязок для конкретного инвентаря
SplitDropAction Действие: сбросить часть стека, не прекращая drag
SlotInteractionAction Базовый класс действия (наследуйте для кастомных)