Interfaces: menús, inputs y NUI · Lección 3/3 · 10 min
NUI propia: cuando los menús no bastan
Para HUDs, teléfonos o tiendas con diseño propio necesitas NUI: una web (HTML/CSS/JS) encima del juego.
Cuando quieres una interfaz con tu propio diseño (un HUD, un teléfono, una tienda bonita) montas una NUI: una página web que FiveM dibuja sobre el juego. Funciona igual con QBCore que sin él.
Declararla y abrir/cerrar con foco
-- fxmanifest.lua
ui_page 'html/index.html'
files { 'html/index.html', 'html/style.css', 'html/app.js' }fxmanifest.lua
-- client.lua
RegisterCommand('tienda', function()
SetNuiFocus(true, true) -- da foco y ratón a la web
SendNUIMessage({ action = 'open' })
end)
RegisterNUICallback('close', function(_, cb)
SetNuiFocus(false, false) -- ¡devuelve el control al juego!
cb('ok')
end)
-- comprar: el cliente solo PIDE; el servidor decide
RegisterNUICallback('comprar', function(data, cb)
QBCore.Functions.TriggerCallback('tienda:comprar', function(ok)
cb({ ok = ok })
end, data.item)
end)client.lua
El bug nº1 de NUI: olvidarse de SetNuiFocus(false, false) al cerrar deja al jugador con el ratón fuera y sin poder moverse. Pon siempre el cierre con ESC y por callback. Y recuerda: la compra real se valida en el SERVIDOR (callback), nunca en el JS.
Practica lo aprendido
0/3Para abrir tu NUI y darle el ratón al jugador, ¿qué llamada necesitas?
Completa la función nativa que manda datos desde Lua hacia la web (JS).
({ action = 'open', data = { dinero = 500 } })Pista
Lua → JS: la web escucha estos mensajes con un addEventListener('message').
Este callback cierra la NUI pero deja al jugador atrapado sin poder moverse. Falta devolverle el control quitando el foco.
Este código tiene un fallo:
RegisterNUICallback('close', function(_, cb) cb('ok')end)Reescríbelo corregido:
Pista
El bug nº1 de NUI: olvidar SetNuiFocus(false, false) al cerrar deja el ratón fuera y bloquea el movimiento.
Reto: prográmalo tú
Crea el esqueleto de una NUI: fxmanifest con ui_page/files, abrir con /tienda dando foco, y un callback 'close' que lo quite.
Escríbelo tú en tu editor (VS Code) y pruébalo en tu servidor. Aquí se aprende haciéndolo, no copiando.
Ver pista
ui_page → /tienda abre con foco → JS escucha 'open' y muestra; ESC hace fetch a 'close' que quita el foco.
Escribe aquí tu solución:
