Konwertuj skrypt QBCore na QBox: qbx_core, ox_inventory, ox_target
Jak portować skrypt QBCore do QBox: warstwa kompatybilności qbx_core, GetPlayer, przedmioty ox_inventory, powiadomienia ox_lib i postęp, ox_target, i co zwykle się psuje.
Masz skrypt napisany dla QBCore i serwer uruchamiający QBox. Czasem się uruchamia i działa, czasem konsola się zapełnia błędami o brakujących qb-inventory, qb-target lub qb-menu. Tutaj jest kolejność, aby go portować, i miejsca, gdzie zwykle się psuje.
Jeśli wciąż wybierasz rdzeń, ta sama praca z drugiej strony jest w convert an ESX script to QBCore.
Co QBox zmienia i co przechowuje
QBox jest zbudowany na qbx_core plus zasoby Overextended: ox_lib, oxmysql, ox_inventory i ox_target. Przechowuje warstwę kompatybilności, więc exports['qb-core']:GetCoreObject() wciąż odpowiada i PlayerData ma taką samą kształt (citizenid, job, charinfo, metadata, money). Dlatego wiele skryptów działa bez zmian.
Co nie przechowuje, to stare zasoby użyteczności QB. Gdzie QBCore używał qb-inventory, qb-target, qb-menu, qb-input i qb-progressbar, QBox oczekuje ox_inventory, ox_target i ox_lib. Te są częściami, które portujesz.
Pierwszy krok to upewnienie się, że rdzeń jest uruchamiany prawidłowo:
ensure oxmysql
ensure ox_lib
ensure qbx_core
ensure ox_inventory
ensure ox_target
ensure my_scriptUsuń dowolny pozostały folder qb-core, ponieważ dwa rdzenie kolidują. Zobacz QBCore is nil: GetCoreObject, jeśli obiekt brakuje.
Krok 1: zależności w manifeście
fx_version 'cerulean'
game 'gta5'
lua54 'yes'
shared_script '@ox_lib/init.lua'
dependencies { 'qbx_core', 'ox_lib', 'ox_inventory', 'ox_target' }@ox_lib/init.lua to co daje ci globalny lib. Jeśli nie zostanie znaleziony, zobacz ox_lib init.lua not found.
Krok 2: uzyskanie gracza
Oba te działają na QBox. Pierwszy to styl kompatybilności, drugi to sposób QBox:
-- QBCore style (still works through the compatibility layer)
local QBCore = exports['qb-core']:GetCoreObject()
local Player = QBCore.Functions.GetPlayer(source)
-- QBox style
local player = exports.qbx_core:GetPlayer(source)
if player then
print(player.PlayerData.citizenid, player.PlayerData.job.name)
endOba zwracają nil dla gracza, który nie jest załadowany, więc przechowaj sprawdzenie nil. Aby znaleźć załadowanego gracza po ID obywatela, QBox ma też GetPlayerByCitizenId. Gdy portujesz, możesz zostawić wołania QBCore na miejscu i zamienić je jedno po drugim później.
Krok 3: inwentarz
To jest gdzie większość skryptów się psuje. qb-inventory i ox_inventory nie mają wspólnych definicji przedmiotów ani nazw funkcji.
| Zadanie | QBCore | QBox z ox_inventory |
|---|---|---|
| Dodaj przedmiot | Player.Functions.AddItem('water', 1) |
exports.ox_inventory:AddItem(source, 'water', 1) |
| Usuń przedmiot | Player.Functions.RemoveItem('water', 1) |
exports.ox_inventory:RemoveItem(source, 'water', 1) |
| Liczba | Player.Functions.GetItemByName('water').amount |
exports.ox_inventory:GetItemCount(source, 'water') |
| Metadane | tabela info |
tabela metadata |
local src = source
local ok = exports.ox_inventory:AddItem(src, 'water', 2, { quality = 100 })
if not ok then
lib.notify(src, { description = 'Your inventory is full', type = 'error' })
endAddItem zwraca wartość fałszywą, gdy przedmiot nie istnieje lub nie może być niesiony, więc go sprawdzić. Definicje przedmiotów też się poruszają. QBCore przechowuje je w qb-core/shared/items.lua, ox_inventory w ox_inventory/data/items.lua. Dodaj każdy przedmiot, który skrypt używa tam, w formacie ox_inventory. Jak to zrobić jest w add items to ox_inventory, i format QBCore, z którego przychodzisz, jest w add items to qb-inventory.
Przedmioty użyteczne są też rejestrowane inaczej: QBCore.Functions.CreateUseableItem staje się export ustawionym w definicji przedmiotu w ox_inventory, który wskazuje na funkcję w twoim skrypcie. Wołania QBCore mogą wciąż działać przez warstwę kompatybilności, więc przetestuj przedmiot przed jego przepisaniem.
Krok 4: powiadomienia, postęp i menu z ox_lib
ox_lib zastępuje osobne zasoby narzędziowe QB. Wołania są zbliżone do tego, co znasz:
-- QBCore
QBCore.Functions.Notify('Done', 'success', 5000)
-- ox_lib (client)
lib.notify({ title = 'Job', description = 'Done', type = 'success', duration = 5000 })-- QBCore: QBCore.Functions.Progressbar(...) with a callback
-- ox_lib: returns true when completed, false when cancelled
if lib.progressBar({
duration = 5000,
label = 'Repairing',
useWhileDead = false,
canCancel = true,
disable = { car = true, move = true },
anim = { dict = 'mini@repair', clip = 'fixing_a_ped' },
}) then
print('finished')
else
print('cancelled')
endMenu przechodzą z qb-menu na lib.registerContext i lib.showContext, a formularze wejściowe z qb-input na lib.inputDialog. Pełne przykłady są w notifications and progress bars on ESX, QBCore and ox_lib i ox_lib context menus.
Krok 5: ox_target zamiast qb-target
qb-target przyjmuje nazwę, współrzędne i tabelę opcji w swoim własnym układzie. ox_target przyjmuje jedną tabelę:
-- qb-target
exports['qb-target']:AddBoxZone('my_zone', vector3(215.0, -810.0, 30.7), 1.5, 1.5, {
name = 'my_zone', heading = 0, minZ = 29.7, maxZ = 32.7,
}, {
options = { { event = 'my_script:client:open', icon = 'fas fa-box', label = 'Open', job = 'police' } },
distance = 2.0,
})
-- ox_target
exports.ox_target:addBoxZone({
coords = vector3(215.0, -810.0, 30.7),
size = vector3(1.5, 1.5, 3.0),
rotation = 0,
options = {
{ name = 'my_zone_open', icon = 'fas fa-box', label = 'Open', groups = 'police',
onSelect = function() TriggerEvent('my_script:client:open') end },
},
})Zauważ event staje się onSelect (lub event wciąż działa dla zdarzenia klienta), i job staje się groups. Szczegóły są w qb-target vs ox_target i ox_target zones.
Co zwykle się psuje
- Błędy brakujących przedmiotów. Przedmiot istnieje w pliku udostępnionym qb-core, ale nie w ox_inventory. Dodaj to.
No such exportdla qb-inventory, qb-target lub qb-menu. Skrypt je wołuje bezpośrednio: portuj te wołania, lub nigdy się nie uruchomi.- Callbacki.
lib.callbackto styl QBox. Jeśli skrypt wciąż używaQBCore.Functions.CreateCallback, przetestuj go i przenieś go na ox_lib, jeśli się nie powiedzie: zobacz server callbacks. - Prace i gangi ze stopniami. QBox ma swoje własne dane pracy i grupy. Przetestuj każde sprawdzenie pracy, szczególnie sprawdzenie czuwania i porównania stopni.
- Mieszane rdzenie. Pozostały zasób
qb-coreuruchomiony obokqbx_core. - Kolejność uruchamiania. Twój skrypt ponad ox_lib, ox_inventory lub qbx_core w
server.cfg.
Lista kontrolna
| Symptom | Naprawa |
|---|---|
GetCoreObject to nil |
Uruchom qbx_core pierwszy i usuń dowolny folder qb-core |
No such export dla qb-inventory |
Użyj exports.ox_inventory:AddItem(source, item, count) |
| Przedmiot nie znaleziony | Dodaj to do ox_inventory/data/items.lua |
| Wołania qb-target się nie powiodą | Portuj na exports.ox_target:addBoxZone lub addLocalEntity |
lib to nil |
Dodaj shared_script '@ox_lib/init.lua' |
| Sprawdzenie pracy zawsze fałsz | Przetestuj PlayerData.job.name i stopień na QBox |
Szybkie odpowiedzi
Czy skrypty QBCore działają na QBox bez zmian?
Wiele tak, ponieważ qbx_core przechowuje warstwę kompatybilności dla qb-core. Skrypty, które zależą od qb-inventory, qb-target lub qb-menu zwykle potrzebują pracy, ponieważ QBox używa ox_inventory, ox_target i ox_lib zamiast tego.
Jak uzyskać gracza na QBox?
Na serwerze, exports.qbx_core:GetPlayer(source) zwraca gracza, z taką samą tabelą PlayerData, którą znasz z QBCore.
Czy muszę przepisać wszystko, aby przenieść się na QBox?
Nie. Uruchom skrypt na QBox, przeczytaj błędy, i zamień części, które się psują: inwentarz, cel, menu i powiadomienia. Reszta, taka jak PlayerData, prace i metadane, zachowuje swój kształt.
Skrypty bez tego problemu
Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →
Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →
Quest CreatorWizualny edytor questów i dialogów z NPC, budowanych węzeł po węźle w grze.Zobacz skrypt →