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:

text
nui_devtools

Ein 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_devtools verfü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:

text
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:

js
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:

js
window.addEventListener('message', (event) => {
  console.log('NUI message', JSON.stringify(event.data))
})

Dann vergleiche es mit dem Lua-Aufruf:

lua
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:

lua
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>:

js
fetch(`https://${GetParentResourceName()}/close`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({}),
})

In der Registerkarte Network zeigt eine fehlgeschlagene Anfrage rot:

text
POST https://my_script/close net::ERR_FAILED

Prüfe diese in der Reihenfolge:

  1. Der Callback ist nicht registriert. Der Name nach dem Schrägstrich muss genau einem RegisterNUICallback auf dem Client entsprechen:
lua
RegisterNUICallback('close', function(data, cb)
    SetNuiFocus(false, false)
    cb('ok')
end)
  1. 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/close fehl. Verwende GetParentResourceName() auf der Seite, wie oben, damit der Name dem Ordner folgt.
  2. Der Callback antwortet niemals. Rufe immer cb(...) auf, auch mit cb('ok'). Ein Handler, der zurückkehrt, ohne ihn aufzurufen, lässt die Anfrage ausstehend, und die Seite kann ewig warten.
  3. Der Lua-Handler hat einen Fehler vor cb. Prüfe die F8-Konsole auf einen Skriptfehler im gleichen Moment. Ein Fehler vor cb bedeutet, dass die Antwort niemals gesendet wird.
  4. 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:

js
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:

js
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 if auf GetParentResourceName.

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 →

Weiterlesen