Debug FiveM NUI: nui_devtools, Konsolenfehler und fehlgeschlagene Callbacks
Debug einen FiveM NUI: öffne Chromium-Entwicklertools mit nui_devtools, lese Uncaught TypeError-Fehler, behebe einen fehlgeschlagenen Abruf zu https://resource/cb und teste die UI in einem Browser.
Deine NUI öffnet sich als leeres Panel, ein Button funktioniert nicht, oder der Cursor erscheint und kein Bildschirm folgt. Es gibt normalerweise keinen Lua-Fehler, weil der Fehler auf der Webseite ist. Du brauchst die Browser-Konsole, und FiveM hat eine. Dieser Leitfaden behandelt, wie man sie öffnet, wie man ihre Fehler liest und wie man deine UI ohne das Spiel testet.
Die Entwicklertools öffnen: nui_devtools
NUI ist eine Chromium-Seite im Spiel. Drücke F8, um die FiveM-Konsole zu öffnen und führe aus:
nui_devtoolsEin Entwicklertools-Fenster öffnet sich für die NUI-Ebene, wie das, das du aus einem Browser kennst. Verwende diese Registerkarten:
- Console: JavaScript-Fehler und deine eigenen
console.log-Zeilen. - Network: jede Anfrage, die die Seite macht, einschließlich der Callbacks zu Lua.
- Elements: das Live-HTML und CSS. Verwende es, um zu sehen, ob dein Element existiert, wie groß es ist und ob es versteckt ist.
- Sources: setze Haltepunkte in deinem Skript.
Achtung: Ob
nui_devtoolsverfügbar ist, hängt von deinen Einstellungen und vom Client-Build ab, den du ausführst. Wenn der Befehl nichts tut, prüfe, dass dein Spiel-Client auf dem neuesten Stand ist, und teste die UI in einem normalen Browser wie unten gezeigt.
Wenn deine UI nur nach einem SendNUIMessage sichtbar ist, öffne die Entwicklertools zuerst und löse die Aktion danach aus, damit du die ankommenden Nachrichten siehst.
Lese die Konsolenfehler
Fehler im Registerkarte Console zeigen die Datei und die Zeile deines Skripts. Die, die du am meisten sehen wirst:
Uncaught TypeError: Cannot read properties of undefined (reading 'items')Dein Code las .items auf etwas, das undefined ist. In NUI kommt dies fast immer von der Nachricht:
window.addEventListener('message', (event) => {
const { action, data } = event.data
if (action === 'open') {
render(data.items) // data is undefined
}
})Prüfe, was Lua wirklich gesendet hat. Drucke die ganze Nachricht zuerst:
window.addEventListener('message', (event) => {
console.log('NUI message', JSON.stringify(event.data))
})Dann vergleiche es mit dem Lua-Aufruf:
SendNUIMessage({ action = 'open', data = { items = items } })Die Schlüssel müssen genau übereinstimmen, einschließlich der Groß-/Kleinschreibung. Ein Feld, das zu nil in Lua gesetzt ist, fehlt in der Nachricht, also ist es undefined in JavaScript.
Andere häufige Fehler:
| Konsolenmeldung | Übliche Ursache |
|---|---|
Uncaught ReferenceError: x is not defined |
Eine Skriptdatei hat sich nicht geladen, oder ein Tippfehler in einem Namen |
Uncaught SyntaxError |
Eine kaputte Skriptdatei, oder eine Bundler-Ausgabe mit dem falschen Pfad |
Failed to load resource: 404 |
Eine Datei ist nicht unter files im fxmanifest aufgelistet, oder der Pfad ist falsch |
Uncaught (in promise) TypeError: Failed to fetch |
Eine Callback-Anfrage ist fehlgeschlagen, siehe unten |
Wenn die Registerkarte Network einen 404 für dein JS, CSS oder Bilder zeigt, füge jede Datei, die die Seite lädt, zu files im Manifest hinzu, und zeige ui_page auf die richtige HTML:
ui_page 'web/index.html'
files {
'web/index.html',
'web/**/*',
}Verwende für einen Vite- oder React-Build den Ausgabeordner, siehe FiveM NUI with React and Vite.
Fehlgeschlagener Abruf zu https://resource/cb
NUI sendet Nachrichten zu Lua mit einer Anfrage zu https://<resource name>/<callback name>:
fetch(`https://${GetParentResourceName()}/close`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}),
})In der Registerkarte Network zeigt eine fehlgeschlagene Anfrage rot:
POST https://my_script/close net::ERR_FAILEDPrüfe diese in der Reihenfolge:
- Der Callback ist nicht registriert. Der Name nach dem Schrägstrich muss genau einem
RegisterNUICallbackauf dem Client entsprechen:
RegisterNUICallback('close', function(data, cb)
SetNuiFocus(false, false)
cb('ok')
end)- Der Ressourcenname ist falsch. Der Host in der URL ist der Ressourcenordnername. Wenn du den Ordner umbenannt hast, schlägt ein hart-kodiertes
https://old_name/closefehl. VerwendeGetParentResourceName()auf der Seite, wie oben, damit der Name dem Ordner folgt. - Der Callback antwortet niemals. Rufe immer
cb(...)auf, auch mitcb('ok'). Ein Handler, der zurückkehrt, ohne ihn aufzurufen, lässt die Anfrage ausstehend, und die Seite kann ewig warten. - Der Lua-Handler hat einen Fehler vor
cb. Prüfe die F8-Konsole auf einen Skriptfehler im gleichen Moment. Ein Fehler vorcbbedeutet, dass die Antwort niemals gesendet wird. - Die Ressource läuft nicht. Callbacks leben so lange wie das Client-Skript, das sie registriert.
Fokus und der Cursor
Wenn die UI angezeigt wird, aber nicht geklickt werden kann, oder die Maus bleibt nach dem Schließen stecken, ist das Problem SetNuiFocus, nicht die Seite. Siehe NUI focus stuck cursor.
Teste die UI in einem normalen Browser
Das Debuggen im Spiel ist langsam. Die meisten einer NUI können in einem Browser mit deinem Editor's Live Reload getestet werden.
Öffne index.html über einen lokalen Server, oder führe npm run dev für ein Vite-Projekt aus. Dann stub die zwei Dinge, die das Spiel normalerweise bereitstellt.
Zunächst ein gefälschter GetParentResourceName und Callbacks, die nicht fehlschlagen:
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 () => ({}) }
}
}Zweitens, sende die Nachrichten, die Lua senden würde. Von der Browser-Konsole, oder ein Dev-Only-Button:
window.postMessage({ action: 'open', data: { items: [{ name: 'water', count: 3 }] } }, '*')Dies ruft deinen message-Listener genau wie SendNUIMessage auf. Du kannst das Design entwerfen, das Layout reparieren und die Datenbehandlung im Browser prüfen, und behalte das Spiel für die letzte Prüfung des Fokus, echte Daten und echte Callbacks.
Tipp: Entferne die Stubs aus dem Produktions-Build, oder wickle sie so, dass sie nur laufen, wenn die Seite außerhalb des Spiels geöffnet wird, wie oben mit dem
ifaufGetParentResourceName.
Checkliste
| Symptom | Behebung |
|---|---|
| Leere NUI | Öffne nui_devtools, lese die Registerkarten Console und Network |
nui_devtools tut nichts |
Aktualisiere den Client und prüfe deine Einstellungen; teste in einem normalen Browser |
Uncaught TypeError ... of undefined |
Protokolliere event.data und passe die Schlüssel an, die von SendNUIMessage gesendet werden |
| 404 für eine Datei | Liste sie unter files auf und prüfe ui_page |
POST https://resource/name schlägt fehl |
Registriere den Callback mit RegisterNUICallback und verwende den genauen Namen |
| Falscher Ressourcenname in der URL | Verwende GetParentResourceName() |
| Button funktioniert, nichts passiert in Lua | Stelle sicher, dass der Callback cb('ok') aufruft |
| Cursor bleibt nach dem Schließen stecken | Rufe SetNuiFocus(false, false) auf |
Kurze Antworten
Wie öffne ich die Entwicklertools für eine FiveM NUI?
Öffne die F8-Konsole im Spiel und führe nui_devtools aus. Ein Chromium-Entwicklertool-Fenster öffnet sich für die NUI-Ebene. Die Verfügbarkeit kann von deinen Einstellungen und deinem Client-Build abhängen.
Warum schlägt mein NUI-Callback fehl?
Die Anfrage zu https://resource_name/callback erreichte Lua nicht. Der Callback ist nicht mit RegisterNUICallback registriert, der Ressourcenname in der URL ist falsch, oder der Callback antwortet niemals mit cb.
Kann ich meine NUI testen, ohne das Spiel zu starten?
Ja. Öffne die Seite in einem normalen Browser oder führe den Vite Dev-Server aus, sende gefälschte Nachrichten mit window.postMessage und stub die Callbacks. Nur das echte Spiel gibt dir Fokus, echte Daten und echte Callbacks.
Scripts ohne dieses Problem
Mic PhoneEin faltbares Handy, das sich zum Tablet aufklappt und bis aufs echte Handy des Spielers reicht.Script ansehen →
Arcade MachinesSieben spielbare Arcade-Games in echten Automaten, mit Bestenlisten und Wetten.Script ansehen →
CCTV Security CamerasPlatzierbare Kameras, ein Live-Tablet mit Multi-View und ausgedruckte Beweisfotos.Script ansehen →