Kursor FiveM zablokowany lub nie może się poruszać po zamknięciu menu: naprawa fokus NUI
Kursor zablokowany na ekranie lub nie może się poruszać po zamknięciu menu? Jak SetNuiFocus pracuje, zamykanie za pomocą NUI callback, obsługa ESC w JavaScript i znalezienie winowajcy.
Zamykasz menu, i jeden z tych rzeczy się dzieje:
the mouse cursor stays on screen
the character will not move or look around
the keyboard does nothing until you reconnectNic nie pokazuje się w konsoli, ponieważ nic nie jest złe z kodem, który uruchamia: on po prostu nigdy nie dał fokus z powrotem. Tutaj jest jak fokus pracuje, jak prawidłowo zamknąć menu i jak znaleźć winowajcę.
Jak NUI fokus pracuje
NUI jest stroną internetową (HTML, CSS i JavaScript) którą FiveM rysuje nad grą. Podczas gdy ma fokus, mysz i klawiatura idą do strony zamiast do gry. Skrypt daje i bierze fokus za pomocą jednego nativa:
SetNuiFocus(hasFocus, hasCursor)SetNuiFocus(true, true): NUI otrzymuje klawiaturę i mysz, i kursor się pokazuje.SetNuiFocus(true, false): NUI otrzymuje klawiaturę, bez kursora.SetNuiFocus(false, false): fokus wraca do gry i kursor się chowa.
Jeśli menu otwiera się z true, true i żaden kod nigdy nie wołuje SetNuiFocus(false, false), gra zostaje zablokowana, nawet jeśli strona jest ukryta.
Naprawa: zawsze zamykaj z SetNuiFocus(false, false)
Umieść zamknięcie w jednej funkcji i użyj jej dla każdego sposobu aby zamknąć menu:
local open = false
local function openMenu()
open = true
SetNuiFocus(true, true)
SendNUIMessage({ action = 'open' })
end
local function closeMenu()
open = false
SetNuiFocus(false, false)
SendNUIMessage({ action = 'close' })
endZrób to samo jeśli menu może być zamknięte przez inny kod: gdy gracz umrze, wejdzie do pojazdu, lub gdy zasób się zatrzyma.
AddEventHandler('onResourceStop', function(resource)
if resource == GetCurrentResourceName() and open then
SetNuiFocus(false, false)
end
end)Ten ostatni liczy się. Jeśli zasób się zatrzyma podczas gdy jego menu jest otwarte, fokus nie jest zwrócony dla ciebie, i gracz jest zablokowany aż się ponownie połączy.
Zamknij ze strony: RegisterNUICallback i fetch
Przycisk zamknięcia, lub wciśnięcie klawisza wewnątrz strony, uruchamia się w JavaScript. JavaScript nie może wołać nativa, więc wysyła żądanie do strony Lua, które je obsługuje:
RegisterNUICallback('close', function(data, cb)
closeMenu()
cb('ok')
end)Na twojej stronie, wyślij żądanie za pomocą fetch do https://<resource name>/close. GetParentResourceName() daje ci nazwę zasobu wewnątrz strony NUI:
function closeMenu() {
fetch(`https://${GetParentResourceName()}/close`, {
method: 'POST',
headers: { 'Content-Type': 'application/json; charset=UTF-8' },
body: JSON.stringify({}),
})
}
document.getElementById('close-button').addEventListener('click', closeMenu)Callback musi wołać cb. Jeśli nigdy nie odpowiada, żądanie na stronie zostaje otwarte, a niektóre biblioteki przestają czekać na niego. Zawsze kończ callback z cb('ok') lub inną odpowiedzią.
ESC i inne klawisz w JavaScript
Podczas gdy NUI ma fokus, gra nie widzi klawiatury, więc klawisz ESC nigdy nie osiąga twojego kodu Lua. Strona musi go nasłuchiwać:
window.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
closeMenu()
}
})Dodaj tę samą kontrolę dla jakiegokolwiek innego klawisza, który powinien zamknąć menu. Jeśli strona ma pole wejściowe, pomyśl o czym klawisz tam robi: ESC w polu tekstowym powinno wciąż zamknąć menu, ale litera nie powinna.
Ostrzeżenie: nie polegaj tylko na przycisku zamknięcia. Jeśli gracz wciśnie ESC i strona nie ma nasłuchiwacza, menu pauzy może się otworzyć, i menu zostaje na ekranie bez żadnego sposobu aby je zamknąć.
Chodzenie podczas gdy menu jest otwarte
Niektóre interfejsy, takie jak HUD z małą panelą lub telefon, powinny pozwolić graczowi wciąż się poruszać. Do tego użyj SetNuiFocusKeepInput:
SetNuiFocus(true, true)
SetNuiFocusKeepInput(true)Z keep input, gra wciąż otrzymuje klawiaturę podczas gdy NUI ma fokus. Jeśli go włączysz, wyłącz go gdy menu się zamyka, ponieważ zostaje włączony aż to zrobisz:
local function closeMenu()
SetNuiFocusKeepInput(false)
SetNuiFocus(false, false)
endPozostawiony SetNuiFocusKeepInput(true) daje dziwne objawy: kursor znika ale niektóre klawisz zachowują się dziwnie lub nic nie robią.
Znajdź zasób który trzyma fokus
Często zablokowane menu nie jest twoje. Gdy nie wiesz który zasób wziął fokus, znajdź go przez eliminację:
- Powtórz problem: otwórz menu, zamknij go, i zobacz kursor zablokowany.
- W konsoli serwera (lub Live Console w txAdmin), wpisz
restart resource_namedla jednego zasobu, który ma menu: telefon, inwentarz, sklep, menu radialne lub menu ubrań. - Sprawdź czy kursor i kontrolki wrócą lub czy problem już się nie dzieje.
- Powtórz dla następnego zasobu aż zachowanie się zmieni.
Gdy restart daje fokus z powrotem, ten skrypt go trzyma. Szukaj w jego kodzie ścieżkę zamknięcia, która nie wołuje SetNuiFocus(false, false): błąd przed linią zamknięcia, śmierć lub zmianę pracy, które zamykają tylko HTML, lub callback, który nie odpowiada. Błąd w konsoli w czasie bugu jest silną wskazówką: patrz jak przeczytać błąd skryptu FiveM.
Jeśli to skrypt który kupiłeś, wyślij jego autorowi dokładne kroki i nazwę zasobu którą znalazłeś.
Checklist
| Objaw | Naprawić |
|---|---|
| Kursor zostaje po zamknięciu | Wołaj SetNuiFocus(false, false) w funkcji zamknięcia |
| Przycisk zamknięcia nic nie robi | Dodaj RegisterNUICallback('close', ...) i fetch do https://<resource>/close |
| ESC nie zamyka menu | Nasłuchuj Escape w JavaScript i wołaj callback zamknięcia |
| Zablokowany po restarcie zasobu | Zwolnij fokus w onResourceStop |
| Postać nie może się poruszać po zamknięciu | Wyłącz SetNuiFocusKeepInput(false) przy zamknięciu |
| Nie wiem który skrypt to robi | Uruchom ponownie zasoby jeden po drugim aż kursor powróci |
| Callback się zawiesza | Zawsze odpowiedz z cb('ok') |
Szybkie odpowiedzi
Dlaczego mój kursor zostaje na ekranie po zamknięciu menu?
Menu ukryło swój HTML, ale nic nie powiedziało grze aby zwróciła fokus. Skrypt musi wołać SetNuiFocus(false, false) gdy menu się zamyka.
Co robi SetNuiFocusKeepInput?
SetNuiFocusKeepInput(true) pozwala grze odbierać wejście klawiatury podczas gdy NUI ma fokus, więc gracz może wciąż chodzić. Musi być wyłączony ponownie gdy menu się zamyka.
Jak znaleźć który zasób trzyma fokus?
Uruchom ponownie zasoby jeden po czasie i sprawdź po każdym czy kursor i kontrolki wrócą. Ten którego restart to naprawia to ten który trzymał fokus.
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 →
Clothing DesignerProjektuj ubrania w FiveM — pędzel, warstwy, import obrazów i AI — a potem je noś.Zobacz skrypt →