Eseguire il debug di FiveM NUI: nui_devtools, errori della console e callback non riusciti
Esegui il debug di una FiveM NUI: apri i devtools di Chromium con nui_devtools, leggi gli errori Uncaught TypeError, correggi un fetch non riuscito a https://resource/cb e testa l'UI in un browser.
La tua NUI si apre come un pannello vuoto, un pulsante non fa nulla, o il cursore appare e nessuna schermata segue. Di solito non c'è un errore Lua, perché il difetto è nella pagina web. Hai bisogno della console del browser, e FiveM ne ha una. Questa guida copre come aprirla, come leggere i suoi errori e come testare la tua UI senza il gioco.
Apri i devtools: nui_devtools
NUI è una pagina Chromium all'interno del gioco. Premi F8 per aprire la console FiveM ed esegui:
nui_devtoolsUna finestra di devtools si apre per il layer NUI, come quella che conosci da un browser. Usa queste schede:
- Console: errori di JavaScript e le tue righe
console.log. - Network: ogni richiesta che la pagina fa, inclusi i callback a Lua.
- Elements: l'HTML e il CSS live. Usalo per vedere se il tuo elemento esiste, quanto è grande e se è nascosto.
- Sources: imposta breakpoint nello script.
Attenzione: se
nui_devtoolsè disponibile dipende dalle impostazioni e dalla build del client che esegui. Se il comando non fa nulla, controlla che il tuo game client sia aggiornato, e testa l'UI in un browser normale come mostrato sotto.
Se la tua UI è visibile solo dopo un SendNUIMessage, apri i devtools prima e attiva l'azione dopo, in modo da vedere i messaggi che arrivano.
Leggi gli errori della console
Gli errori nella scheda Console mostrano il file e la riga dello script. Quelli che vedrai più spesso:
Uncaught TypeError: Cannot read properties of undefined (reading 'items')Il tuo codice ha letto .items su qualcosa che è undefined. In NUI questo quasi sempre viene dal messaggio:
window.addEventListener('message', (event) => {
const { action, data } = event.data
if (action === 'open') {
render(data.items) // data is undefined
}
})Controlla cosa Lua ha veramente inviato. Stampa l'intero messaggio prima:
window.addEventListener('message', (event) => {
console.log('NUI message', JSON.stringify(event.data))
})Poi confrontalo con la chiamata Lua:
SendNUIMessage({ action = 'open', data = { items = items } })Le chiavi devono corrispondere esattamente, inclusa la capitalizzazione. Un campo impostato su nil in Lua manca dal messaggio, quindi è undefined in JavaScript.
Altri errori comuni:
| Messaggio della console | Causa usuale |
|---|---|
Uncaught ReferenceError: x is not defined |
Un file di script non ha caricato, o un errore di digitazione in un nome |
Uncaught SyntaxError |
Un file di script rotto, o un output del bundler con il percorso sbagliato |
Failed to load resource: 404 |
Un file non è elencato in files nel fxmanifest, o il percorso è sbagliato |
Uncaught (in promise) TypeError: Failed to fetch |
Una richiesta di callback ha fallito, vedi sotto |
Se la scheda Network mostra un 404 per il tuo JS, CSS o immagini, aggiungi ogni file che la pagina carica a files nel manifesto, e punta ui_page all'HTML corretto:
ui_page 'web/index.html'
files {
'web/index.html',
'web/**/*',
}Per una build Vite o React, usa la cartella di output, vedi FiveM NUI con React e Vite.
Fetch non riuscito a https://resource/cb
NUI invia messaggi a Lua con una richiesta a https://<resource name>/<callback name>:
fetch(`https://${GetParentResourceName()}/close`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}),
})Nella scheda Network una richiesta non riuscita è mostrata in rosso:
POST https://my_script/close net::ERR_FAILEDControlla questi in ordine:
- Il callback non è registrato. Il nome dopo la barra deve corrispondere a un
RegisterNUICallbacksul client, esattamente:
RegisterNUICallback('close', function(data, cb)
SetNuiFocus(false, false)
cb('ok')
end)- Il nome della risorsa è sbagliato. L'host nell'URL è il nome della cartella della risorsa. Se hai rinominato la cartella, un
https://old_name/closehardcoded fallisce. UsaGetParentResourceName()nella pagina, come sopra, così il nome segue la cartella. - Il callback non risponde mai. Chiama sempre
cb(...), anche concb('ok'). Un handler che ritorna senza chiamarlo lascia la richiesta in sospeso, e la pagina può aspettare per sempre. - L'handler Lua errori prima di
cb. Controlla la console F8 per un errore di script allo stesso momento. Un errore prima dicbsignifica che la risposta non è mai inviata. - La risorsa non è in esecuzione. I callback vivono finché lo script client che li ha registrati.
Focus e cursore
Se l'UI mostra ma non può essere cliccata, o il mouse rimane bloccato dopo la chiusura, il problema è SetNuiFocus, non la pagina. Vedi Cursore bloccato di NUI focus.
Testa l'UI in un browser normale
Il debug in gioco è lento. La maggior parte di un NUI può essere testata in un browser, con il live reload del tuo editor.
Apri index.html attraverso un server locale, o esegui npm run dev per un progetto Vite. Poi crea un mock delle due cose che il gioco normalmente fornisce.
Primo, un falso GetParentResourceName, e callback che non falliscono:
if (!window.GetParentResourceName) {
window.GetParentResourceName = () => 'my_script'
window.fetch = async (url, options) => {
console.log('NUI callback', url, options && options.body)
return { ok: true, json: async () => ({}) }
}
}Secondo, invia i messaggi che Lua invierebbe. Dalla console del browser, o un pulsante solo per sviluppo:
window.postMessage({ action: 'open', data: { items: [{ name: 'water', count: 3 }] } }, '*')Questo chiama il tuo listener message esattamente come SendNUIMessage farebbe. Puoi progettare, correggere il layout e controllare la gestione dei dati nel browser, e mantenere il gioco per il controllo finale di focus, dati reali e callback reali.
Consiglio: rimuovi i mock dalla build di produzione, o avvolgili in modo che vengano eseguiti solo quando la pagina è aperta al di fuori del gioco, come sopra con l'
ifsuGetParentResourceName.
Checklist
| Sintomo | Soluzione |
|---|---|
| NUI vuota | Apri nui_devtools, leggi le schede Console e Network |
nui_devtools non fa nulla |
Aggiorna il client e controlla le impostazioni; testa in un browser normale |
Uncaught TypeError ... of undefined |
Registra event.data e corrisponde alle chiavi inviate da SendNUIMessage |
| 404 per un file | Elencalo in files e controlla ui_page |
POST https://resource/name fallisce |
Registra il callback con RegisterNUICallback e usa il nome esatto |
| Nome della risorsa sbagliato nell'URL | Usa GetParentResourceName() |
| Il pulsante funziona, nulla accade in Lua | Assicurati che il callback chiami cb('ok') |
| Cursore bloccato dopo la chiusura | Chiama SetNuiFocus(false, false) |
Risposte rapide
Come apro i devtools per una FiveM NUI?
Apri la console F8 in gioco ed esegui nui_devtools. Una finestra di devtools di Chromium si apre per il layer NUI. La disponibilità può dipendere dalle impostazioni e dalla build del client.
Perché il mio callback NUI fallisce?
La richiesta a https://resource_name/callback non ha raggiunto Lua. Il callback non è registrato con RegisterNUICallback, il nome della risorsa nell'URL è sbagliato, o il callback non risponde mai con cb.
Posso testare la mia NUI senza avviare il gioco?
Sì. Apri la pagina in un browser normale o esegui il server di sviluppo Vite, invia messaggi falsi con window.postMessage, e mock i callback. Solo il gioco vero ti dà il focus, i dati veri e i callback veri.
Script senza questo problema
Mic PhoneUn telefono pieghevole che si apre in un tablet e arriva sul telefono vero del giocatore.Vedi script →
Arcade MachinesSette giochi arcade giocabili in cabinati veri, con classifiche e scommesse.Vedi script →
CCTV Security CamerasTelecamere posizionabili, un tablet multi-vista in diretta e foto stampate come prove.Vedi script →