Déboguer FiveM NUI : nui_devtools, erreurs de console et rappels échoués
Déboguer une NUI FiveM : ouvrez les outils de développement Chromium avec nui_devtools, lisez les erreurs Uncaught TypeError, corrigez une récupération échouée vers https://resource/cb et testez l'interface utilisateur dans un navigateur.
Votre NUI s'ouvre en tant que panneau vide, un bouton ne fait rien, ou le curseur apparaît et aucun écran ne suit. Il y a généralement aucune erreur Lua, car la faute est dans la page web. Vous avez besoin de la console du navigateur, et FiveM en a une. Ce guide couvre comment l'ouvrir, comment lire ses erreurs et comment tester votre interface utilisateur sans le jeu.
Ouvrir les outils de développement : nui_devtools
NUI est une page Chromium à l'intérieur du jeu. Appuyez sur F8 pour ouvrir la console FiveM et exécutez :
nui_devtoolsUne fenêtre d'outils de développement s'ouvre pour la couche NUI, comme celle que vous connaissez d'un navigateur. Utilisez ces onglets :
- Console : erreurs JavaScript et vos propres lignes
console.log. - Network : chaque demande que la page effectue, y compris les rappels à Lua.
- Elements : le HTML et CSS en direct. Utilisez-le pour voir si votre élément existe, sa taille et s'il est masqué.
- Sources : définissez des points d'arrêt dans votre script.
Attention : que
nui_devtoolssoit disponible dépend de vos paramètres et de la build client que vous exécutez. Si la commande ne fait rien, vérifiez que le client de votre jeu est à jour, et testez l'interface utilisateur dans un navigateur normal comme indiqué ci-dessous.
Si votre interface utilisateur n'est visible que après un SendNUIMessage, ouvrez d'abord les outils de développement et déclenchez l'action après, afin que vous voyiez les messages qui arrivent.
Lire les erreurs de la console
Les erreurs dans l'onglet Console montrent le fichier et la ligne de votre script. Celles que vous verrez le plus :
Uncaught TypeError: Cannot read properties of undefined (reading 'items')Votre code a lu .items sur quelque chose qui est undefined. Dans NUI, cela provient presque toujours du message :
window.addEventListener('message', (event) => {
const { action, data } = event.data
if (action === 'open') {
render(data.items) // data is undefined
}
})Vérifiez ce que Lua a vraiment envoyé. Imprimez d'abord le message entier :
window.addEventListener('message', (event) => {
console.log('NUI message', JSON.stringify(event.data))
})Ensuite, comparez-le à l'appel Lua :
SendNUIMessage({ action = 'open', data = { items = items } })Les clés doivent correspondre exactement, y compris la casse. Un champ défini à nil en Lua est absent du message, donc il est undefined en JavaScript.
Autres erreurs courantes :
| Message de la console | Cause habituelle |
|---|---|
Uncaught ReferenceError: x is not defined |
Un fichier de script ne s'est pas chargé, ou une faute de frappe dans un nom |
Uncaught SyntaxError |
Un fichier de script cassé, ou une sortie bundler avec le mauvais chemin |
Failed to load resource: 404 |
Un fichier n'est pas listé dans files dans le fxmanifest, ou le chemin est incorrect |
Uncaught (in promise) TypeError: Failed to fetch |
Une demande de rappel a échoué, voir ci-dessous |
Si l'onglet Réseau affiche un 404 pour votre JS, CSS ou images, ajoutez chaque fichier que la page charge à files dans le manifeste, et pointez ui_page vers le bon HTML :
ui_page 'web/index.html'
files {
'web/index.html',
'web/**/*',
}Pour une build Vite ou React, utilisez le dossier de sortie, voir FiveM NUI with React and Vite.
Récupération échouée vers https://resource/cb
NUI envoie des messages à Lua avec une demande à https://<resource name>/<callback name> :
fetch(`https://${GetParentResourceName()}/close`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}),
})Dans l'onglet Réseau, une demande échouée s'affiche en rouge :
POST https://my_script/close net::ERR_FAILEDVérifiez ceci dans l'ordre :
- Le rappel n'est pas enregistré. Le nom après la barre oblique doit correspondre à un
RegisterNUICallbacksur le client, exactement :
RegisterNUICallback('close', function(data, cb)
SetNuiFocus(false, false)
cb('ok')
end)- Le nom de ressource est incorrect. Le hôte dans l'URL est le nom du dossier de ressource. Si vous avez renommé le dossier, un
https://old_name/closecodé en dur échoue. UtilisezGetParentResourceName()dans la page, comme ci-dessus, afin que le nom suive le dossier. - Le rappel ne répond jamais. Appelez toujours
cb(...), même aveccb('ok'). Un gestionnaire qui retourne sans l'appeler laisse la demande en attente, et la page peut attendre indéfiniment. - Le gestionnaire Lua erreur avant
cb. Vérifiez la console F8 pour une erreur de script au même moment. Une erreur avantcbsignifie que la réponse n'est jamais envoyée. - La ressource n'est pas en cours d'exécution. Les rappels vivent aussi longtemps que le script client qui les a enregistrés.
Focus et le curseur
Si l'interface utilisateur s'affiche mais ne peut pas être cliquée, ou si la souris reste coincée après la fermeture, le problème est SetNuiFocus, pas la page. Voir NUI focus stuck cursor.
Testez l'interface utilisateur dans un navigateur normal
Le débogage en jeu est lent. La plupart d'une NUI peut être testée dans un navigateur, avec le rechargement en direct de votre éditeur.
Ouvrez index.html via un serveur local, ou exécutez npm run dev pour un projet Vite. Ensuite, effectuez une stub des deux choses que le jeu fournit normalement.
Premièrement, un faux GetParentResourceName, et des rappels qui ne échouent pas :
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 () => ({}) }
}
}Deuxièmement, envoyez les messages que Lua enverrait. Depuis la console du navigateur, ou un bouton dev uniquement :
window.postMessage({ action: 'open', data: { items: [{ name: 'water', count: 3 }] } }, '*')Cela appelle votre écouteur message exactement comme SendNUIMessage le fait. Vous pouvez concevoir, corriger la mise en page et vérifier la manipulation des données dans le navigateur, et conserver le jeu pour la vérification finale du focus, des données réelles et des vrais rappels.
Astuce : supprimez les stubs de la build de production, ou enveloppez-les pour qu'ils ne s'exécutent que lorsque la page est ouverte en dehors du jeu, comme ci-dessus avec le
ifsurGetParentResourceName.
Liste de contrôle
| Symptôme | Correction |
|---|---|
| NUI vierge | Ouvrez nui_devtools, lisez les onglets Console et Réseau |
nui_devtools ne fait rien |
Mettez à jour le client et vérifiez vos paramètres ; testez dans un navigateur normal |
Uncaught TypeError ... of undefined |
Connectez event.data et faites correspondre les clés envoyées par SendNUIMessage |
| 404 pour un fichier | Le lister dans files et vérifier ui_page |
POST https://resource/name échoue |
Enregistrer le rappel avec RegisterNUICallback et utiliser le nom exact |
| Nom de ressource incorrect dans l'URL | Utiliser GetParentResourceName() |
| Le bouton fonctionne, rien ne se passe dans Lua | S'assurer que le rappel appelle cb('ok') |
| Curseur coincé après la fermeture | Appeler SetNuiFocus(false, false) |
Réponses rapides
Comment ouvrir les outils de développement pour une NUI FiveM ?
Ouvrez la console F8 en jeu et exécutez nui_devtools. Une fenêtre d'outils de développement Chromium s'ouvre pour la couche NUI. La disponibilité peut dépendre de vos paramètres et de votre build client.
Pourquoi mon rappel NUI échoue-t-il ?
La demande à https://resource_name/callback n'a pas atteint Lua. Le rappel n'est pas enregistré avec RegisterNUICallback, le nom de ressource dans l'URL est incorrect, ou le rappel ne répond jamais avec cb.
Puis-je tester mon NUI sans démarrer le jeu ?
Oui. Ouvrez la page dans un navigateur normal ou exécutez le serveur de développement Vite, envoyez des messages faux avec window.postMessage, et effectuez une stub des rappels. Seul le vrai jeu vous donne le focus, les données réelles et les vrais rappels.
Des scripts sans ce problème
Mic PhoneUn téléphone pliable qui se déplie en tablette et se prolonge jusqu’au vrai téléphone du joueur.Voir le script →
Arcade MachinesSept jeux d’arcade jouables dans de vraies bornes, avec classements et paris.Voir le script →
CCTV Security CamerasDes caméras à placer, une tablette multi-vues en direct et des photos imprimées comme preuves.Voir le script →