Debuguj FiveM NUI: nui_devtools, błędy konsoli i nieudane callback'i
Debuguj FiveM NUI: otwórz devtools Chromium za pomocą nui_devtools, przeczytaj błędy Uncaught TypeError, napraw nieudane pobieranie do https://resource/cb i przetestuj UI w przeglądarce.
Twój NUI otwiera się jako pusta panel, przycisk nic nie robi, lub kursor pojawia się i żaden ekran nie następuje. Zwykle nie ma błędu Lua, ponieważ wina jest w stronie internetowej. Potrzebujesz konsoli przeglądarki, a FiveM ją ma. Ten przewodnik obejmuje jak ją otworzyć, jak przeczytać jej błędy i jak przetestować UI bez gry.
Otwórz devtools: nui_devtools
NUI jest stroną Chromium wewnątrz gry. Wciśnij F8 aby otworzyć konsolę FiveM i uruchom:
nui_devtoolsOkno devtools otwiera się dla warstwy NUI, takie jak to znasz z przeglądarki. Użyj tych zakładek:
- Console: Błędy JavaScript i twoje własne linie
console.log. - Network: każde żądanie które strona wysyła, włącznie z callback'ami do Lua.
- Elements: żywy HTML i CSS. Użyj go aby zobaczyć czy twój element istnieje, jak duży jest i czy jest ukryty.
- Sources: ustaw punkty przerwania w twoim skrypcie.
Ostrzeżenie: czy
nui_devtoolsjest dostępny zależy od twoich ustawień i kompilacji klienta którą uruchamiasz. Jeśli polecenie nic nie robi, sprawdź że twój klient gry jest zaktualizowany, i przetestuj UI w normalnej przeglądarce jak pokazano poniżej.
Jeśli twój UI jest widoczny tylko po SendNUIMessage, otwórz devtools najpierw i wyzwól akcję potem, aby zobaczyć wiadomości które docierają.
Przeczytaj błędy konsoli
Błędy w karcie Console pokazują plik i linię twojego skryptu. Te które zobaczysz najczęściej:
Uncaught TypeError: Cannot read properties of undefined (reading 'items')Twój kod przeczytał .items na czymś to jest undefined. W NUI to prawie zawsze pochodzi z wiadomości:
window.addEventListener('message', (event) => {
const { action, data } = event.data
if (action === 'open') {
render(data.items) // data is undefined
}
})Sprawdź co Lua naprawdę wysłała. Wydrukuj całą wiadomość najpierw:
window.addEventListener('message', (event) => {
console.log('NUI message', JSON.stringify(event.data))
})Następnie porównaj to do wołania Lua:
SendNUIMessage({ action = 'open', data = { items = items } })Klucze muszą dokładnie pasować, włącznie z wielkością liter. Pole ustawione na nil w Lua brakuje z wiadomości, więc to jest undefined w JavaScript.
Inne czaste błędy:
| Wiadomość konsoli | Zwykła przyczyna |
|---|---|
Uncaught ReferenceError: x is not defined |
Plik skryptu nie załadował się, lub błąd pisowni w nazwie |
Uncaught SyntaxError |
Uszkodzony plik skryptu, lub wynik bundlera ze złą ścieżką |
Failed to load resource: 404 |
Plik nie jest wymieniony w files w fxmanifest, lub ścieżka jest zła |
Uncaught (in promise) TypeError: Failed to fetch |
Żądanie callback'u nie powiodło się, zobacz poniżej |
Jeśli karta Network pokazuje 404 dla twojego JS, CSS lub obrazów, dodaj każdy plik który strona ładuje do files w manifeście, i wskaż ui_page na prawidłowy HTML:
ui_page 'web/index.html'
files {
'web/index.html',
'web/**/*',
}Dla kompilacji Vite lub React, użyj folderu wyjściowego, patrz FiveM NUI with React and Vite.
Nieudane pobieranie do https://resource/cb
NUI wysyła wiadomości do Lua za pomocą żądania do https://<resource name>/<callback name>:
fetch(`https://${GetParentResourceName()}/close`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}),
})W karcie Network nieudane żądanie pokazuje się na czerwono:
POST https://my_script/close net::ERR_FAILEDSprawdź te w kolejności:
- Callback nie jest zarejestrowany. Nazwa po ukośniku musi dokładnie pasować do
RegisterNUICallbackna kliencie:
RegisterNUICallback('close', function(data, cb)
SetNuiFocus(false, false)
cb('ok')
end)- Nazwa zasobu jest zła. Host w URL to nazwa folderu zasobu. Jeśli przemianowałeś folder, hardcoded
https://old_name/closenie powiedzie się. UżyjGetParentResourceName()na stronie, jak powyżej, aby nazwa podążyła za folderem. - Callback nigdy nie odpowiada. Zawsze wołaj
cb(...), nawet zcb('ok'). Obsługa, która wraca bez wołania go zostawia żądanie oczekujące, a strona może czekać wiecznie. - Obsługa Lua błędów przed
cb. Sprawdź konsolę F8 dla błędu skryptu w tym samym momencie. Błąd przedcboznacza że odpowiedź nigdy nie jest wysłana. - Zasób nie jest uruchomiony. Callback'i żyją tak długo jak skrypt klienta, który je zarejestrował.
Fokus i kursor
Jeśli UI pokazuje ale nie może być klikięty, lub mysz zostaje zablokowana po zamknięciu, problem to SetNuiFocus, nie strona. Patrz NUI focus stuck cursor.
Przetestuj UI w normalnej przeglądarce
Debugowanie w grze jest powolne. Większość NUI może być przetestowana w przeglądarce, z live reload'em twojego edytora.
Otwórz index.html poprzez lokalny serwer, lub uruchom npm run dev dla projektu Vite. Następnie zastępuj dwie rzeczy które gra normalnie dostarcza.
Pierwsza, fałszywy GetParentResourceName, i callback'i które nie zawiodą:
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 () => ({}) }
}
}Druga, wyślij wiadomości które Lua byłaby wysłała. Z konsoli przeglądarki, lub guzika dev-only:
window.postMessage({ action: 'open', data: { items: [{ name: 'water', count: 3 }] } }, '*')To wołuje twojego nasłuchiwacza message dokładnie jak SendNUIMessage. Możesz projektować, naprawiać układ i sprawdzać obsługę danych w przeglądarce, i trzymać grę dla ostatecznego sprawdzenia fokus, rzeczywistych danych i rzeczywistych callback'i.
Porada: usuń zastępujące z kompilacji produkcji, lub owrap'uj je aby uruchomiły się tylko gdy strona jest otwarta poza grą, jak powyżej z
ifnaGetParentResourceName.
Checklist
| Objaw | Naprawić |
|---|---|
| Pusta NUI | Otwórz nui_devtools, przeczytaj karty Console i Network |
nui_devtools nic nie robi |
Zaktualizuj klienta i sprawdź ustawienia; przetestuj w normalnej przeglądarce |
Uncaught TypeError ... of undefined |
Zaloguj event.data i dopasuj klucze wysłane przez SendNUIMessage |
| 404 dla pliku | Wymień go w files i sprawdź ui_page |
POST https://resource/name nie powiedzie się |
Zarejestruj callback z RegisterNUICallback i użyj dokładnej nazwy |
| Zła nazwa zasobu w URL | Użyj GetParentResourceName() |
| Przycisk działa, nic się nie dzieje w Lua | Upewnij się że callback wołuje cb('ok') |
| Kursor zablokowany po zamknięciu | Wołaj SetNuiFocus(false, false) |
Szybkie odpowiedzi
Jak otworzyć devtools dla FiveM NUI?
Otwórz konsolę F8 w grze i uruchom nui_devtools. Okno devtools Chromium otwiera się dla warstwy NUI. Dostępność może zależeć od twoich ustawień i kompilacji klienta.
Dlaczego mój callback NUI nie powiedzie się?
Żądanie do https://resource_name/callback nie osiągnęło Lua. Callback nie jest zarejestrowany z RegisterNUICallback, nazwa zasobu w URL jest zła, lub callback nigdy nie odpowiada z cb.
Czy mogę przetestować mój NUI bez uruchamiania gry?
Tak. Otwórz stronę w normalnej przeglądarce lub uruchom serwer Vite dev, wyślij fałszywe wiadomości za pomocą window.postMessage, i zastępuj callback'i. Tylko prawdziwa gra daje ci fokus, rzeczywiste dane i rzeczywiste callback'i.
Skrypty bez tego problemu
Mic PhoneSkładany telefon, który rozkłada się w tablet i działa też na prawdziwym telefonie gracza.Zobacz skrypt →
Arcade MachinesSiedem grywalnych gier arcade w prawdziwych automatach, z rankingami i zakładami.Zobacz skrypt →
CCTV Security CamerasKamery do rozstawienia, tablet z podglądem wielu kamer na żywo i drukowane zdjęcia jako dowody.Zobacz skrypt →