Przejdź do głównej zawartości

Konwencje UI / NUI

Każdy zasób ma własną stronę NUI (ui_page 'html/index.html'). bs_ui to HUD, powiadomienia i wspólne elementy.

Gdy twój panel się otwiera, ogłaszasz to. Każdy inny panel to słyszy i sam się zamyka. Gdy twój się zamyka, też to ogłaszasz. Prawdziwy kod z bs_config:

local function close()
if not isOpen then return end
isOpen = false
SetNuiFocus(false, false)
SendNUIMessage({ action = 'close' })
TriggerEvent('bs:ui:closed', 'config')
end
local function open()
if isOpen then return close() end
isOpen = true
SetNuiFocus(true, true)
SendNUIMessage({ action = 'open', data = data })
TriggerEvent('bs:ui:opened', 'config')
end
-- another UI took over: step aside
AddEventHandler('bs:ui:opened', function(what)
if what ~= 'config' and isOpen then close() end
end)
AddEventHandler('onResourceStop', function(res)
if res == GetCurrentResourceName() and isOpen then
SetNuiFocus(false, false)
TriggerEvent('bs:ui:closed', 'config')
end
end)

Zasady:

  • Podawaj nazwę swojego panelu w obu zdarzeniach. Handlery ją sprawdzają, a handler reagujący na każde zamknięcie przez miesiące psuł mapę terenu.
  • Ogłaszaj parę przy każdym wyjściu: przycisk zamknięcia, Esc, klawisz przełączania, otwarcie innego UI, zatrzymanie zasobu. Pomiń jedno, a gracz zostaje z kursorem myszy i bez gry.
  • Ogłoś opened po otwarciu i zamykaj się z własnego handlera, nie zakładaj, że zrobią to inni.

/refreshui (bs_ui) to przycisk paniki: zamyka wszystko, zwalnia fokus i wywołuje bs:ui:closed z nil.

-- client
TriggerEvent('bs:ui:notify', { type = 'info', title = 'Radio', message = 'Signal found.', duration = 3000 })
-- server
TriggerClientEvent('bs:ui:notify', src, { type = 'error', title = 'Denied', message = 'Nope.' })

Typy używane w kodzie: info, success, error.

Strony są układane pod 1920x1080. Dołącz wspólny skaler, żeby pasowały do każdej rozdzielczości:

<script src="https://cfx-nui-bs_ui/html/shared/scale.js"></script>

Skaluje <body> przez transform: --ui-scale = clamp(min(w/1920, h/1080), 0.6, 1.25). Gracze mogą go nadpisać (0.6 do 1.4) w ustawieniach.

Rzeczy, które warto wiedzieć:

  • W CSS strony pisz vh/vw jako calc(Nvh / var(--ui-scale, 1)), żeby pozostały prawdziwymi ułamkami okna.
  • JS ustawiający style.left/top z clientX/clientY lub bounding rect musi dzielić przez BSScale.get(). BSScale.w() / BSScale.h() dają lokalny viewport.
  • Rezygnacja przez <html data-bs-noscale>.
  • html, body { background: transparent !important; } na każdej stronie. Inaczej dostajesz czarny ekran nad grą.
  • Żadnych wiadomości NUI co klatkę w bezczynności. Wysyłaj przy zmianie lub z ograniczeniem (HUD drona wysyła co 150 ms w locie, to mniej więcej maksimum).
  • Paleta to bursztyn / rdza / kość / kurz na prawie czerni. Używaj tokenów CSS bs_ui i bs_menu/html/css/faction-hub.css. Bez zewnętrznych czcionek i CDN, gracze mogą nie mieć do nich dostępu, a to też kwestia prywatności.
  • Ikony: liniowe ikony w bs_ui/html/js/icons.js.
  • Dźwięki: bs_ui/html/js/sound.js obsługuje dźwięki pozycyjne (maxDistance, panoramowanie).