Контекстное меню ox_lib: registerContext, inputDialog и alertDialog

Построение меню в FiveM с ox_lib: lib.registerContext и lib.showContext с подменю и значками, плюс lib.inputDialog и lib.alertDialog, и исправление 'lib' равного nil.

Вы вызываете lib.registerContext и консоль говорит:

text
attempt to index a nil value (global 'lib')

Или код меню запускается и ничего не открывается. Эта статья охватывает инструменты меню ox_lib: контекстное меню, диалог ввода и диалог оповещения, с строкой манифеста, которая делает lib существующим.

Загрузите ox_lib в ваш манифест

lib — это глобальное значение, которое ox_lib добавляет в ваш ресурс через файл инициализации. Без него каждый вызов lib. не работает с ошибкой выше. В fxmanifest.lua:

lua
fx_version 'cerulean'
game 'gta5'
lua54 'yes'

shared_script '@ox_lib/init.lua'

client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }

Затем запустите ox_lib перед вашим скриптом в server.cfg:

cfg
ensure ox_lib
ensure my_script

Если файл вообще не найден, смотрите @ox_lib/init.lua not found.

Контекстное меню

Контекстное меню — это список щёлкаемых опций. Вы регистрируете его один раз под id, затем показываете его, когда он вам нужен. Оба вызова — на стороне клиента:

lua
lib.registerContext({
    id = 'my_script_main',
    title = 'Garage',
    options = {
        {
            title = 'Take out a vehicle',
            description = 'Choose from your parked vehicles',
            icon = 'car',
            onSelect = function()
                print('take out')
            end,
        },
        {
            title = 'Store vehicle',
            description = 'Park the vehicle you are in',
            icon = 'warehouse',
            onSelect = function()
                print('store')
            end,
        },
        {
            title = 'Impound',
            description = 'Not available',
            icon = 'lock',
            disabled = true,
        },
    },
})

lib.showContext('my_script_main')

Опции, которые вы будете использовать чаще всего:

Поле Что оно делает
title Основной текст опции.
description Вторая строка текста под названием.
icon Имя значка Font Awesome, например car. Вы также можете передать полный класс, такой как fa-solid fa-car.
onSelect Функция, которая запускается при нажатии опции.
menu Id другого контекстного меню для открытия (подменю).
arrow Показывает стрелку справа, намёк на то, что это что-то открывает.
disabled Затемняет опцию, чтобы её нельзя было щёлкнуть.

Существуют другие поля, такие как event, serverEvent, args, metadata и progress. Проверьте документацию ox_lib для вашей версии.

Подменю

Чтобы открыть подменю, дайте опцию menu с id следующего контекстного меню. Дайте второму контекстному меню menu, указывающий на первый, и оно получит кнопку 'назад':

lua
lib.registerContext({
    id = 'my_script_main',
    title = 'Garage',
    options = {
        {
            title = 'My vehicles',
            icon = 'car',
            arrow = true,
            menu = 'my_script_vehicles',
        },
    },
})

lib.registerContext({
    id = 'my_script_vehicles',
    title = 'My vehicles',
    menu = 'my_script_main',
    options = {
        {
            title = 'Sultan',
            description = 'Plate ABC 123',
            onSelect = function()
                print('selected Sultan')
            end,
        },
    },
})

lib.showContext('my_script_main')

Совет: таблица опций строится при регистрации меню. Для списка, который изменяется, такого как транспортные средства игрока, постройте таблицу и вызовите lib.registerContext ещё раз прямо перед lib.showContext. Регистрация того же id снова заменяет старое меню.

lib.hideContext() закрывает меню из кода.

Попросите ввод с inputDialog

lib.inputDialog открывает форму и ждёт, пока игрок подтвердит или отменит. Это возвращает таблицу со значениями в порядке строк, или nil, если игрок отменил:

lua
local input = lib.inputDialog('New shop', {
    { type = 'input', label = 'Shop name', required = true },
    { type = 'number', label = 'Price', default = 100, min = 0 },
    { type = 'checkbox', label = 'Open to everyone' },
})

if not input then return end

local name, price, open = input[1], input[2], input[3]
print(name, price, open)

Другие типы строк включают select, slider и textarea. select принимает список опций:

lua
local input = lib.inputDialog('Pick a colour', {
    {
        type = 'select',
        label = 'Colour',
        options = {
            { value = 'red', label = 'Red' },
            { value = 'blue', label = 'Blue' },
        },
    },
})

if input then print(input[1]) end

Потому что вызов ждёт, запустите его в потоке или в обработчике, которому разрешено ждать, такой как функция onSelect. Никогда не проверяйте только на клиенте. Когда значение идёт на сервер, проверьте его там также.

Подтвердите с alertDialog

lib.alertDialog — это окно да/нет. Это возвращает 'confirm' или 'cancel':

lua
local alert = lib.alertDialog({
    header = 'Delete the shop?',
    content = 'This cannot be undone.',
    centered = true,
    cancel = true,
})

if alert == 'confirm' then
    print('deleting')
end

Без cancel = true есть только кнопка OK.

Используйте его из цели или команды

Меню обычно открывается чем-то другим. С ox_target вызовите lib.showContext в onSelect (смотрите ox_target: как добавлять цели). С командой вызовите её в обработчике:

lua
RegisterCommand('garage', function()
    lib.showContext('my_script_main')
end, false)

Зарегистрируйте контекстные меню сначала, в начале файла клиента или при запуске скрипта, так чтобы id существовал, когда команда запускается.

Контрольный список

Симптом Решение
attempt to index a nil value (global 'lib') Добавьте shared_script '@ox_lib/init.lua' и запустите ox_lib первым
lib.showContext открывает ничего Зарегистрируйте id с lib.registerContext перед его показом
Подменю не имеет кнопки 'назад' Установите menu в подменю на id родителя
Меню показывает устаревшие данные Зарегистрируйте её снова с новыми опциями перед lib.showContext
inputDialog возвращает nil Игрок отменил: проверьте на nil
Значок не появляется Используйте допустимое имя Font Awesome, или полный класс как fa-solid fa-car

Короткие ответы

Почему lib равен nil в моём скрипте?

Ваш манифест не загружает файл инициализации ox_lib. Добавьте shared_script '@ox_lib/init.lua' и убедитесь, что ox_lib запускается перед вашим ресурсом.

Как сделать подменю?

Зарегистрируйте второе контекстное меню со своим id, затем дайте опцию в первом меню menu = 'second_id'. Установите menu = 'first_id' на втором, так оно получит кнопку 'назад'.

Как я прочитаю, что написал игрок?

lib.inputDialog возвращает таблицу с одним значением за строку в порядке, или nil, если игрок отменил. Всегда проверяйте на nil.

Скрипты без этой проблемы

Item Creator V2Создавайте используемые предметы с анимациями, пропами, эффектами и не только — без кода.Смотреть скрипт →Shop CreatorМагазин меньше чем за минуту — владельцы, сотрудники, сейфы и ограбления в комплекте.Смотреть скрипт →Quest CreatorВизуальный редактор квестов и диалогов с NPC — узел за узлом прямо в игре.Смотреть скрипт →

Читайте также