Menú contextual de ox_lib: registerContext, inputDialog y alertDialog

Construye menús en FiveM con ox_lib: lib.registerContext y lib.showContext con submenús e iconos, además lib.inputDialog y lib.alertDialog, y soluciona que 'lib' sea nil.

Llamas a lib.registerContext y la consola dice:

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

O el código del menú se ejecuta y nada se abre. Este artículo cubre las herramientas de menú de ox_lib: el menú contextual, el diálogo de entrada y el diálogo de alerta, con la línea de manifest que hace que lib exista.

Carga ox_lib en tu manifest

lib es un global que ox_lib añade a tu recurso a través de su archivo init. Sin él, cada llamada a lib. falla con el error anterior. En fxmanifest.lua:

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

shared_script '@ox_lib/init.lua'

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

Luego inicia ox_lib antes que tu script en server.cfg:

cfg
ensure ox_lib
ensure my_script

Si el archivo no se puede encontrar en absoluto, véase @ox_lib/init.lua not found.

Un menú contextual

Un menú contextual es una lista de opciones en las que se puede hacer clic. Lo registras una vez bajo una id, luego lo muestras cuando lo necesitas. Ambas llamadas están en el lado del cliente:

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')

Las opciones que usarás más:

Campo Qué hace
title El texto principal de la opción.
description Una segunda línea de texto bajo el título.
icon Un nombre de icono Font Awesome, como car. También puedes pasar una clase completa como fa-solid fa-car.
onSelect Función que se ejecuta cuando se hace clic en la opción.
menu La id de otro contexto para abrir (un submenú).
arrow Muestra una flecha a la derecha, una pista de que abre algo.
disabled Desactiva la opción para que no se pueda hacer clic.

Otros campos existen, como event, serverEvent, args, metadata y progress. Verifica la documentación de ox_lib para la versión que ejecutas.

Para abrir un submenú, da a la opción menu con la id del siguiente contexto. Da al segundo contexto un menu que apunte de nuevo al primero, y obtiene un botón de atrás:

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')

Consejo: la tabla de opciones se construye cuando registras el menú. Para una lista que cambia, como los vehículos de un jugador, construye la tabla y llama a lib.registerContext de nuevo justo antes de lib.showContext. Registrar la misma id de nuevo reemplaza el menú antiguo.

lib.hideContext() cierra el menú desde el código.

Solicita entrada con inputDialog

lib.inputDialog abre un formulario y espera hasta que el jugador confirme o cancele. Devuelve una tabla con los valores en orden de fila, o nil si el jugador canceló:

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)

Otros tipos de fila incluyen select, slider y textarea. Un select toma una lista de opciones:

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

Porque la llamada espera, ejecútala en un hilo o en un controlador que se permite esperar, como una función onSelect. Nunca valides solo en el cliente. Cuando el valor va al servidor, veríficalo también allí.

Confirma con alertDialog

lib.alertDialog es una ventana sí/no. Devuelve 'confirm' o '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

Sin cancel = true hay solo un botón de OK.

Úsalo desde un objetivo o un comando

Un menú generalmente se abre por algo más. Con ox_target, llama a lib.showContext en onSelect (véase ox_target: how to add targets). Con un comando, llámalo en el controlador:

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

Registra los contextos primero, en la parte superior del archivo del cliente o cuando el script se inicia, así que la id existe cuando se ejecuta el comando.

Lista de verificación

Síntoma Solución
attempt to index a nil value (global 'lib') Añade shared_script '@ox_lib/init.lua' e inicia ox_lib primero
lib.showContext no abre nada Registra la id con lib.registerContext antes de mostrarla
El submenú no tiene botón de atrás Establece menu en el submenú a la id padre
El menú muestra datos obsoletos Registralo de nuevo con las nuevas opciones antes de lib.showContext
inputDialog devuelve nil El jugador canceló: verifica nil
El ícono no aparece Usa un nombre Font Awesome válido, o una clase completa como fa-solid fa-car

Respuestas rápidas

¿Por qué lib es nil en mi script?

Tu manifest no carga el archivo init de ox_lib. Añade shared_script '@ox_lib/init.lua' y asegúrate de que ox_lib se inicia antes que tu recurso.

¿Cómo hago un submenú?

Registra un segundo contexto con su propia id, luego da la opción en el primer menú menu = 'second_id'. Establece menu = 'first_id' en el segundo para que obtenga un botón de atrás.

¿Cómo leo lo que escribió el jugador?

lib.inputDialog devuelve una tabla con un valor por fila, en orden, o nil si el jugador canceló. Siempre verifica nil.

Scripts que evitan este problema

Item Creator V2Crea items usables con animaciones, props, efectos y más — sin escribir código.Ver script →Shop CreatorCrea una tienda en menos de un minuto — dueños, empleados, caja fuerte y atracos.Ver script →Quest CreatorUn editor visual de misiones y diálogos con NPC, nodo a nodo dentro del juego.Ver script →

Sigue leyendo