Aller au contenu

Conventions UI / NUI

Chaque ressource a sa propre page NUI (ui_page 'html/index.html'). bs_ui est le HUD, les notifications et les éléments partagés.

Un panneau à la fois : bs:ui:opened / bs:ui:closed

Section intitulée « Un panneau à la fois : bs:ui:opened / bs:ui:closed »

Quand votre panneau s’ouvre, vous l’annoncez. Tous les autres panneaux l’entendent et se ferment. Quand le vôtre se ferme, vous l’annoncez aussi. Code réel de 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)

Règles :

  • Passez le nom de votre panneau dans les deux événements. Les handlers le vérifient ; un handler qui réagissait à n’importe quelle fermeture a cassé la carte de terrain pendant des mois.
  • Appariez-les sur chaque sortie : bouton de fermeture, Échap, touche de bascule, ouverture d’une autre UI, arrêt de la ressource. Si vous en ratez une, le joueur reste coincé avec un curseur de souris et plus de jeu.
  • Annoncez opened une fois ouvert, et fermez-vous depuis votre propre handler, ne supposez pas que les autres le feront.

/refreshui (bs_ui) est le bouton panique : il ferme tout, libère le focus et déclenche bs:ui:closed avec 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.' })

Types utilisés dans le code : info, success, error.

Les pages sont conçues pour 1920x1080. Incluez le scaler partagé pour qu’elles s’adaptent à toute résolution :

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

Il met <body> à l’échelle avec un transform : --ui-scale = clamp(min(w/1920, h/1080), 0.6, 1.25). Les joueurs peuvent le modifier (0.6 à 1.4) dans les paramètres.

À savoir quand vous l’utilisez :

  • Dans le CSS de la page, écrivez vh/vw sous la forme calc(Nvh / var(--ui-scale, 1)), pour qu’ils restent de vraies fractions du viewport.
  • Le JS qui définit style.left/top à partir de clientX/clientY ou d’un bounding rect doit diviser par BSScale.get(). BSScale.w() / BSScale.h() donnent le viewport local.
  • Désactivez avec <html data-bs-noscale>.
  • html, body { background: transparent !important; } sur chaque page. Sinon, un écran noir recouvre le jeu.
  • Pas de messages NUI à chaque frame au repos. Envoyez au changement, ou limitez (le HUD du drone envoie toutes les 150 ms en vol, c’est à peu près le maximum).
  • La palette est ambre / rouille / os / poussière sur presque noir. Réutilisez les tokens CSS de bs_ui et bs_menu/html/css/faction-hub.css. Pas de polices ni de CDN externes : les joueurs n’ont peut-être pas d’accès internet pour cela, et c’est de toute façon une question de vie privée.
  • Icônes : icônes en ligne dans bs_ui/html/js/icons.js.
  • Sons : bs_ui/html/js/sound.js gère les sons positionnels (maxDistance, panoramique).