Exporty FiveM w Lua: exports('name', fn) i « No such export »
Jak definiować i wywoływać exporty w Lua FiveM, style fxmanifest exports i server_exports oraz jak naprawić błędy « No such export » spowodowane kolejnością startu lub złą stroną.
Skrypt wzywa inny, a konsola odpowiada:
No such export getCount in resource my_inventoryTen artykuł pokazuje, jak exporty są definiowane i wywoływane w Lua, dwie sposoby ich deklaracji i zwykłe powody, że błąd się pojawia.
Definiowanie exportu
Export pozwala jednemu zasobowi oferować funkcję innym. Prostym sposobem jest funkcja exports wewnątrz skryptu:
-- my_inventory/server/main.lua
local function getCount(source, item)
-- ...
return 5
end
exports('getCount', getCount)Możesz również przekazać funkcję wewnątrz:
exports('getCount', function(source, item)
return 5
end)To wszystko. Nie ma nic do dodania do fxmanifest.lua, i export istnieje na stronie, którą uruchamia skrypt: umieść go w skrypcie serwera i to jest export serwera, umieść go w skrypcie klienta i to jest export klienta.
Styl manifestu
Starsze zasoby deklarują exporty w fxmanifest.lua i definiują zwykłą globalną funkcję o tej samej nazwie:
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
server_exports { 'getCount' }
exports { 'getOwnedCount' }-- server script
function getCount(source, item)
return 5
endexports { … }wyświetla klienckie exporty.server_exports { … }wyświetla serwerowe exporty.
To wciąż działa, i wiele zasobów ESX i QBCore go używa. Dwa style się nie konfliktują, więc zasób może je mieszać. Dla nowego kodu, exports('name', fn) jest prostszy, ponieważ funkcja i export mieszkają razem, i nie możesz zapomnieć linię w manifeście. Pamiętaj, że fxmanifest.lua to nazwa aktualnego manifestu: patrz fxmanifest vs __resource.lua.
Wywoływanie exportu
Z każdego innego zasobu po tej samej stronie:
local count = exports['my_inventory']:getCount(source, 'water')Wersje z kropką i dwukropkiem to to samo, o ile nazwa jest prawidłowym identyfikatorem Lua:
local count = exports.my_inventory:getCount(source, 'water')Używaj formy nawiasu, gdy nazwa zasobu ma myślnik, takie jak exports['qb-core']:GetCoreObject(). Wezwanie jest synchroniczne: zwraca wartość funkcji i może mieć opóźnienie, jeśli funkcja czeka.
Porada: argumenty i zwracane wartości podróżują między zasobami, więc tabele są kopiowane. Zmiana tabeli, którą otrzymałeś z exportu, nie zmienia własnych danych innego zasobu. Funkcje wewnątrz zwróconej tabeli wciąż działają, ponieważ odwołują się z powrotem do właściciela.
Dlaczego dostajesz « No such export »
No such export getCount in resource my_inventorySprawdzić to, w tej kolejności:
- Zasób nie jest uruchomiony. Otwórz konsolę i uruchom
ensure my_inventory. Jeśli uruchamia się nie powiedzie, napraw to najpierw. - Uruchomił się po dzwoniącym. Export istnieje dopiero po załadowaniu skryptów właściciela. Patrz start order in server.cfg i umieść właściciela powyżej skryptów, które go używają.
- Nazwa jest źle napisana. Nazwy exportu są czułe na wielkość liter:
getCountiGetCountto różne rzeczy. - Zła strona. Skrypt serwera nie może wezwać export klienta i odwrotnie. Błąd wygląda tak samo.
- Export jest deklarowany, ale funkcja brakuje. Ze stylem manifestu,
server_exports { 'getCount' }potrzebuje globalnej funkcji o nazwiegetCountna serwerze. Lokalna funkcja się nie liczy. - Właściciel się nie powiedzie lub został zatrzymany. Jeśli upadł na błąd skryptu, lub go zatrzymałeś, jego exporty są znikęły, dopóki nie uruchomi się ponownie. Przeczytaj jego dane wyjściowe startu w konsoli.
W przypadku rzeczywistych wersji tego błędu, patrz No such export GetSharedObject in resource es_extended i QBCore is nil: GetCoreObject.
Upewniaj się w kolejności zależnościami
Nie polegaj tylko na kolejności linii ensure. Zadeklaruj zależność w manifeście skryptu, który wzywa export:
dependency 'my_inventory'FiveM następnie uruchamia my_inventory najpierw, i odmawia uruchomienia twojego zasobu, jeśli brakuje, z jaśniejszą wiadomością (could not find dependency).
Elegancko obsługuj brakujący zasób
Jeśli inny zasób jest opcjonalny, sprawdzić jego stan przed wezwaniem go:
if GetResourceState('my_inventory') == 'started' then
local count = exports.my_inventory:getCount(source, 'water')
endGetResourceState zwraca ciąg taki jak started, stopped, starting lub missing. To czysty sposób na wspieranie opcjonalnej integracji bez błędu konsoli.
Wywoływanie własnych exportów
Zasób może również wywoływać własne exporty, z własną nazwą: exports['my_inventory']:getCount(...). Dla funkcji, która jest używana tylko wewnątrz zasobu, normalna lokalna funkcja jest szybsza i prostsza. Exporty są dla granicy między zasobami.
Słowo o wydajności
Każde wezwanie przecina między dwoma zasobami, więc jest wolniejsze niż normalne wezwanie funkcji. Nie wywoływaj exportu w ścisłej per-ramkowej pętli, jeśli możesz przeczytać wartość raz i ją trzymać. Wezwanie jednego kilka razy na sekundę jest w porządku.
Lista kontrolna
| Objaw | Naprawa |
|---|---|
No such export x in resource y |
Uruchom y i umieść go przed dzwoniącym w server.cfg |
| Działa na serwerze, nie powiedzie się na kliencie | Definiuj export w skrypcie klienta także, lub wezwij go z serwera |
| Eksport stylu manifestu brakuje | Definiuj globalną funkcję o tej samej nazwie co wpis manifestu |
| Przypadek nazwy różnię | Dopasuj pisowni dokładnie |
| Nazwa zasobu ma myślnik | exports['my-resource']:name() |
| Opcjonalna integracja spamuje konsolę | Sprawdzić GetResourceState('x') == 'started' najpierw |
Szybkie odpowiedzi
Jak wezwę export z innego zasobu?
Użyj exports['resource_name']:exportName(args) lub exports.resource_name:exportName(args). Inny zasób musi być uruchomiony i musi definiować ten export na tej samej stronie (klient lub serwer).
Czy wciąż potrzebuję exportów w fxmanifest.lua?
Nie z exports('name', fn): to rejestruje export z samego skryptu. Listy exports {} i server_exports {} w manifeście to starszy styl, gdzie globalna funkcja jest ujawniana po nazwie.
Dlaczego export działa na kliencie, ale nie na serwerze?
Exporty klienta i serwera są oddzielne. Export zdefiniowany w skrypcie klienta istnieje tylko na kliencie, a zdefiniowany w skrypcie serwera tylko na serwerze.
Skrypty bez tego problemu
Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →
Mic PhoneSkładany telefon, który rozkłada się w tablet i działa też na prawdziwym telefonie gracza.Zobacz skrypt →
Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →