Подробный гайд по bindKey в Multi Theft Auto (MTA:SA)
bindKey — одна из базовых клиентских функций MTA, позволяющая привязать нажатие клавиши или кнопки мыши к Lua-функции. Широко используется для создания кастомных интерфейсов, админ-панелей, систем взаимодействия, управления транспортом и т.д.
Важно: bindKey работает только на клиенте. Попытка вызвать её в серверном скрипте вернёт false и вызовет ошибку в логах.
Синтаксис
bool bindKey(key, keyState, handlerFunction, [arguments...])
| Параметр | Тип | Описание |
|---|---|---|
key |
string / int |
Название клавиши (рекомендуется) или её скан-код. Примеры: "f", "lctrl", "mouse1", "mwheeldown", "escape" |
keyState |
string |
Состояние срабатывания: "down", "up", "both" |
handlerFunction |
function |
Lua-функция, которая будет вызвана при срабатывании |
arguments... |
any (опционально) |
Дополнительные параметры, которые будут переданы в обработчик |
Возвращаемое значение:
true — привязка успешно создана, false — ошибка (неверная клавиша, вызов на сервере и т.п.).
Типы состояний (keyState)
| Значение | Когда срабатывает | Поведение |
|---|---|---|
"down" |
В момент нажатия | Вызывается один раз |
"up" |
В момент отпускания | Вызывается один раз |
"both" |
И при нажатии, и при отпускании | Вызывается дважды. Первым аргументом в обработчик приходит реальное состояние ("down" или "up"), затем ваши параметры |
Параметры обработчика
Сигнатура функции-обработчика зависит от keyState:
-- Для "down" / "up"
function onKey(key, arg1, arg2, ...)
-- Для "both"
function onKey(key, actualState, arg1, arg2, ...)
-- actualState будет "down" или "up"
key в обработчике всегда передаётся как строка, даже если вы указали скан-код.
Примеры использования
1. Базовое нажатие ("down")
local function openMenu(key)
outputChatBox("Меню открыто по клавише " .. key, 255, 255, 0)
end
bindKey("m", "down", openMenu)
2. С дополнительными параметрами
local function toggleFeature(key, featureName, isEnabled)
outputChatBox(string.format("%s: %s", featureName, isEnabled and "ВКЛ" or "ВЫКЛ"), 0, 255, 0)
end
bindKey("k", "down", toggleFeature, "Подсветка", true)
3. Обработка "both" (нажатие + отпускание)
local function onAction(key, state)
if state == "down" then
outputChatBox("Нажато", 255, 0, 0)
else
outputChatBox("Отпущено", 0, 255, 0)
end
end
bindKey("lshift", "both", onAction)
4. Взаимодействие с сервером
local function requestVehicle(key)
triggerServerEvent("onPlayerRequestVehicle", localPlayer)
end
bindKey("v", "down", requestVehicle)
(На сервере нужно обработать onPlayerRequestVehicle и выполнить действия)
Связанные функции
| Функция | Описание |
|---|---|
unbindKey(key, keyState, handlerFunction) |
Отменяет привязку. Обязательно указывайте ту же функцию, что и при bindKey |
isKeyBound(key, keyState, handlerFunction) |
Возвращает true, если привязка активна |
getBoundKeys(key) |
Возвращает таблицу всех привязок для указанной клавиши |
getKeyState(key) |
Проверяет текущее состояние клавиши в реальном времени (без привязки) |
setControlState(control, state) |
Программно "нажимает" стандартное управление GTA/MTA |
Важные особенности и ограничения
1. Клиентская сторона только
Вызов bindKey в server-скрипте всегда вернёт false. Для серверной логики используйте triggerServerEvent.
2. Перезапись привязок
Если привязать новую функцию к той же key + keyState, старая привязка удаляется автоматически. Чтобы избежать конфликтов, используйте unbindKey перед новой привязкой или проверяйте через isKeyBound.
3. Системные клавиши
Некоторые клавиши (escape, pause, tab, f1-f12) могут быть зарезервированы MTA или GTA. Привязка возможна, но может потребовать отключения стандартного поведения через setGameSpeed, showChat, showCursor и т.п.
4. Раскладка клавиатуры
MTA использует виртуальные коды, поэтому "f" сработает независимо от языка ввода (RU/EN). Это преимущество перед onClientKey.
5. Жизненный цикл ресурса
Рекомендуется привязывать клавиши в onClientResourceStart и отвязывать в onClientResourceStop:
addEventHandler("onClientResourceStart", resourceRoot, function()
bindKey("h", "down", showHelp)
end)
addEventHandler("onClientResourceStop", resourceRoot, function()
unbindKey("h", "down", showHelp)
end)
Лучшие практики
| Делайте | Избегайте |
|---|---|
Всегда проверяйте возвращаемое значение bindKey |
Игнорировать результат привязки |
Храните ссылки на функции в локальных переменных для unbindKey |
Использовать анонимные функции, если нужно будет отвязать |
Документируйте используемые клавиши в meta.xml или чате |
Занимать стандартные клавиши (w, a, s, d, space, enter) без веской причины |
| Очищать привязки при смене режима/респауне/выходе из меню | Оставлять "висячие" привязки после закрытия интерфейса |
Использовать "down" для мгновенных действий, "up" для подтверждения |
Назначать критические действия на "down", если игрок может случайно нажать |
Распространённые ошибки
| Ошибка | Причина | Решение |
|---|---|---|
bindKey возвращает false |
Вызов на сервере / неверное имя клавиши | Проверить тип скрипта (<type>client</type>), использовать список валидных клавиш |
| Обработчик не вызывается | Функция была перезаписана / ресурс остановлен | Убедиться, что bindKey вызван после старта, проверить isKeyBound |
| Конфликт с другим ресурсом | Два ресурса биндят одну клавишу | Использовать уникальные модификаторы (lctrl+f), координировать с другими авторами |
| Память "течёт" | Привязки не удаляются при выходе из интерфейса | Всегда вызывать unbindKey в onClientResourceStop или при закрытии GUI |
Мы делимся этой технической информацией, чтобы помочь вам в решении задач — используйте её с пониманием. Статья носит рекомендательный характер, поэтому, пожалуйста, применяйте описанные методы осмотрительно.