Powiadomienia FiveM i paski postępu: ESX, QBCore i ox_lib

Wysyłaj powiadomienia i pokazuj paski postępu na ESX, QBCore i ox_lib za pomocą ShowNotification, Functions.Notify, lib.notify i lib.progressBar, plus jedna funkcja mostu.

Każdy framework ma swój własny sposób pokazania wiadomości lub paska postępu, a skrypt napisany dla jednego nie powiedzie się na innym:

text
attempt to index a nil value (global 'lib')

Ten artykuł wymienia wywoły dla ESX, QBCore i ox_lib, dla powiadomień i pasków postępu, a następnie pokazuje jedną funkcję mostu aby twój skrypt pracował na którymkolwiek serwer uruchamia.

Powiadomienia na ESX

Na kliencie:

lua
ESX.ShowNotification('You picked up a package')

Na serwerze, z obiektu gracza:

lua
local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.showNotification('Your order is ready')

ESX tutaj jest obiektem z ESX = exports['es_extended']:getSharedObject(). Ostatnie wersje ESX także akceptują typ i czas trwania po tekście. Jeśli polegasz na nich, przetestuj na twojej wersji.

Powiadomienia na QBCore

Na kliencie:

lua
local QBCore = exports['qb-core']:GetCoreObject()

QBCore.Functions.Notify('You picked up a package', 'success', 5000)

Typ to 'primary', 'success' lub 'error', a ostatnia wartość to czas w milisekundach. Z serwera, wyślij zdarzenie do gracza:

lua
TriggerClientEvent('QBCore:Notify', source, 'Your order is ready', 'success')

Na QBox te same wywoły QBCore nie powiedzie się poprzez jego warstwę kompatybilności, a powiadomienia ox_lib są dobrą alternatywą.

Powiadomienia z ox_lib

ox_lib ma swoje własne powiadomienie, i pracuje tak samo na każdym framework. Na kliencie:

lua
lib.notify({
    title = 'Delivery',
    description = 'You picked up a package',
    type = 'success',
    duration = 5000,
})

Typ to 'inform', 'success', 'warning' lub 'error'. Z serwera, wyzwól zdarzenie na graczu:

lua
TriggerClientEvent('ox_lib:notify', source, {
    title = 'Delivery',
    description = 'Your order is ready',
    type = 'success',
})

Globalna lib potrzebuje shared_script '@ox_lib/init.lua' w twoim fxmanifest.lua, jak opisano w przewodniku menu kontekstowego ox_lib. Bez tego dostajesz błąd lib nil powyżej.

Paski postępu

Z ox_lib, pasek postępu jest wywołaniem które czeka i zwraca czy się skończyło:

lua
if lib.progressBar({
    duration = 5000,
    label = 'Repairing the engine',
    useWhileDead = false,
    canCancel = true,
    disable = {
        move = true,
        car = true,
        combat = true,
    },
    anim = {
        dict = 'mini@repair',
        clip = 'fixing_a_ped',
    },
}) then
    print('finished')
else
    print('cancelled')
end

lib.progressCircle bierze te same opcje i pokazuje okrąg zamiast paska. Oba mogą także dołączyć prop do gracza.

Wersja QBCore używa callback'u zamiast czekania:

lua
QBCore.Functions.Progressbar('repair_engine', 'Repairing the engine', 5000, false, true, {
    disableMovement = true,
    disableCarMovement = true,
    disableMouse = false,
    disableCombat = true,
}, {
    animDict = 'mini@repair',
    anim = 'fixing_a_ped',
    flags = 49,
}, {}, {}, function()
    print('finished')
end, function()
    print('cancelled')
end)

Argumenty są, w kolejności: nazwa, etykieta, czas trwania, useWhileDead, canCancel, wyłączone kontrolki, animacja, dwa propsy, a następnie callback'i skończeń i anulowania. ESX nie ma własnego paska postępu które każdy serwer dzieli, więc na ESX użyj lib.progressBar.

Jedna funkcja mostu dla nich wszystkich

Aby trzymać skrypty bez frameworku, napisz szczegół frameworku raz i wołaj swoje własne funkcje wszędzie. Umieść to w pliku klienta:

lua
local function started(name)
    return GetResourceState(name) == 'started'
end

function Notify(message, notifyType)
    notifyType = notifyType or 'inform'

    if started('ox_lib') then
        lib.notify({ description = message, type = notifyType })
    elseif started('qb-core') then
        local qbType = notifyType == 'inform' and 'primary' or notifyType
        exports['qb-core']:GetCoreObject().Functions.Notify(message, qbType)
    elseif started('es_extended') then
        exports['es_extended']:getSharedObject().ShowNotification(message)
    else
        print(message)
    end
end

-- returns true when finished, false when cancelled
function Progress(label, duration)
    if started('ox_lib') then
        return lib.progressBar({
            duration = duration,
            label = label,
            canCancel = true,
            disable = { move = true, car = true },
        })
    end

    local p = promise.new()
    exports['qb-core']:GetCoreObject().Functions.Progressbar('bridge_progress', label, duration, false, true, {
        disableMovement = true,
        disableCarMovement = true,
    }, {}, {}, {}, function() p:resolve(true) end, function() p:resolve(false) end)
    return Citizen.Await(p)
end

Teraz twój skrypt tylko wołuje Notify('Done', 'success') i Progress('Working', 5000). Jeśli ox_lib jest zainstalowany, jest użyty pierwszy. W przeciwnym wypadku QBCore jest użyty, a powiadomienia wracają do ESX.

Fallback pasek postępu tylko obejmuje QBCore. Na serwerze z nie ox_lib ani QBCore, dodaj swoją własną gałąź lub zrób ox_lib wymaganą zależnością z dependency 'ox_lib'.

Porada: zrób to samo na serwerze z jedną funkcją NotifyPlayer(source, message, type), używając wołań serwera z sekcji powyżej. Wtedy żaden inny plik nie musi wiedzieć który framework uruchamia.

Checklist

Objaw Naprawić
attempt to index a nil value (global 'lib') Dodaj shared_script '@ox_lib/init.lua' i uruchom ox_lib pierwszy
Powiadomienie serwera nic nie robi Wyzwól zdarzenie klienta z source gracza jako drugi argument
Powiadomienie QBCore nie ma koloru Użyj ważnego typu: 'primary', 'success' lub 'error'
Pasek postępu blokuje resztę funkcji lib.progressBar czeka: uruchom to w wątku lub obsłudze
Gracz może chodzić podczas paska Ustaw disable (ox_lib) lub disableMovement (QBCore)
Skrypt musi pracować na ESX i QBCore Użyj funkcji mostu i wołaj tylko te

Szybkie odpowiedzi

Jak wysłać powiadomienie z serwera?

Na ESX użyj xPlayer.showNotification(msg). Na QBCore użyj TriggerClientEvent('QBCore:Notify', source, msg, 'success'). Z ox_lib użyj TriggerClientEvent('ox_lib:notify', source, { description = msg, type = 'success' }).

Czy lib.progressBar blokuje skrypt?

Tak. Czeka aż pasek się skończy i zwraca true, lub false jeśli gracz anulował. Uruchom to w wątku lub obsłudze zdarzenia, nie w miejscu które nie może czekać.

Dlaczego lib jest nil gdy wywoływam lib.notify?

Twój manifest nie ma shared_script '@ox_lib/init.lua', lub ox_lib nie jest uruchomiony przed twoim zasobem.

Skrypty bez tego problemu

Quest CreatorWizualny edytor questów i dialogów z NPC, budowanych węzeł po węźle w grze.Zobacz skrypt →Advanced BoostingBoosting pojazdów z tabletu: kontrakty od klasy D do S+, ekipy i kolejka na żywo.Zobacz skrypt →Mic PhoneSkładany telefon, który rozkłada się w tablet i działa też na prawdziwym telefonie gracza.Zobacz skrypt →

Czytaj dalej