Клавиши, мышь и переназначение
Различайте физическую клавишу и символ, сохраняйте привязки геймпада и корректно захватывайте мышь.
Действие вместо клавиши
Для движения и игровых команд задавайте имена в Input Map. Так код одинаков для клавиатуры и геймпада. Для печати текста используйте элементы LineEdit и TextEdit, а не перечень игровых действий.
| Поле InputEventKey | Когда нужно |
|---|---|
PhysicalKeycode | Физическое положение клавиши: например, привычное расположение WASD независимо от раскладки |
Keycode | Латинское обозначение клавиши в текущей раскладке, например S для Ctrl + S |
KeyLabel | Локализованная надпись на клавише для подсказки игроку |
Unicode | Введённый символ; этого недостаточно для полноценного текстового поля с IME |
Переназначьте только клавиатуру
Следующий класс не прикрепляется к Entity. Сохраните его в KeyboardBindings.cs. Вызов KeyboardBindings.SetPhysicalKey("interact", Key.F) заменяет клавиатурные привязки существующего действия и сохраняет мышь и геймпад:
using Reckfell;
public static class KeyboardBindings
{
public static Error SetPhysicalKey(string action, Key key)
{
if (!InputMap.HasAction(action))
return Error.DoesNotExist;
foreach (InputEvent binding in InputMap.ActionGetEvents(action))
{
if (binding is InputEventKey)
InputMap.ActionEraseEvent(action, binding);
}
InputMap.ActionAddEvent(action, new InputEventKey { PhysicalKeycode = key });
return Error.Ok;
}
}Проверяйте результат: неизвестное действие вернёт Error.DoesNotExist. Переназначайте после завершения захвата события, чтобы новая клавиша не выполнила игровую команду в том же событии. На время экрана привязок отключите игровое управление; предусмотрите отмену и восстановление стандартных значений.
Изменения Input Map во время игры не сохраняются автоматически в project.reckfell. Запишите выбранные привязки в user:// и восстановите их при запуске. Сохраняйте имя действия, вид события, код клавиши и модификаторы, если ваш интерфейс их поддерживает. Сохранение данных.
Камера и мышь
Для обзора от первого лица установите Input.MouseMode = Input.MouseModeEnum.Captured. В событии InputEventMouseMotion используйте ScreenRelative для смещения в экранных координатах; Relative зависит от масштабирования содержимого окна. Это уже смещение события — не умножайте его на delta как скорость.
При открытии меню возвращайте Input.MouseModeEnum.Visible и отключайте поворот камеры. При закрытии меню захватывайте мышь снова только намеренно. Отдельно проверьте потерю фокуса окна и выход из режима захвата.
Геймпад
Для стика задайте положительное и отрицательное направления действий и читайте их через GetVector(). Подберите мёртвую зону на настоящем устройстве: слишком маленькая вызывает дрейф, слишком большая ухудшает точность. Обрабатывайте отключение контроллера; не привязывайте логику игры к единственному постоянному номеру устройства.