attempt to call a nil value (field, global, method): jak to naprawić
Otrzymujesz 'attempt to call a nil value' w FiveM? Co oznaczają warianty field, global i method oraz jak naprawić literówkę, brakujący eksport lub błąd dwukropek-kontra-kropka.
W konsoli:
SCRIPT ERROR: @my_script/server/main.lua:42: attempt to call a nil value (field 'GetPlayerFromId')
SCRIPT ERROR: @my_script/client/main.lua:17: attempt to call a nil value (global 'DrawText3D')
SCRIPT ERROR: @my_script/client/main.lua:63: attempt to call a nil value (method 'Notify')Lua mówi ci, że linia próbowała uruchomić funkcję, która nie istnieje. Ten artykuł wyjaśnia trzy warianty, zwyczajne przyczyny i jak naprawić każdą z nich.
Co błąd oznacza
W Lua brakująca nazwa sama w sobie nie jest błędem: przeczytanie jej daje nil. Błąd pojawia się tylko wtedy, gdy umieścisz nawiasy po niej, ponieważ nie możesz uruchomić nil. Tekst w nawiasach mówi, jak skrypt osiągnął brakującą funkcję:
attempt to call a nil value (global 'X'): nagie wezwanie, takie jakX(). Funkcja nie jest nigdzie zdefiniowana, gdzie skrypt może widzieć.attempt to call a nil value (field 'X'): wezwanie przez tabelę, takie jakESX.X()lubQBCore.Functions.X(). Tabela istnieje, ale nie ma wpisu o nazwieX.attempt to call a nil value (method 'X'): wezwanie z dwukropkiem, takie jakobj:X(). Obiekt istnieje, ale nie ma metodyX.
Plik i linia na przedzie wiadomości (@my_script/server/main.lua:42) to linia, która robi wezwanie. Jeśli nie jesteś pewien, jak przeczytać resztę wyjścia, przeczytaj jak przeczytać błąd skryptu FiveM.
1. Literówka w nazwie
Lua jest czuła na wielkość liter. GetPlayerFromId i getPlayerFromId to dwie różne nazwy, i podobnie TriggerClientEvent i TriggerclientEvent. Porównaj nazwę w błędzie z dokumentacją frameworku, litera po literze.
2. Funkcja nie istnieje w twojej wersji
Frameworki zmieniają nazwę i usuwają funkcje. To jest najczęstsza przyczyna na skryptach, które były napisane dla innej wersji twojego frameworku.
-- an old call that may be gone on your version
local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.getInventoryItem('bread')Sprawdź, co twój framework naprawdę oferuje. Wydrukuj tabelę, aby zobaczyć jej wpisy:
for name, value in pairs(ESX) do
print(name, type(value))
endJeśli funkcja, której potrzebujesz, nie jest na liście, skrypt i framework się nie pasują. Zaktualizuj framework, zaktualizuj skrypt, lub zastąp wezwanie tym, który ma twoja wersja.
3. Eksport brakuje
Eksporty to funkcje, które inny zasób dostarcza. Gdy zasób jest zatrzymany, nie powiódł się uruchomić, lub nie eksportuje tej nazwy, wezwanie zawala się.
local core = exports['qb-core']:GetCoreObject()
core.Functions.GetPlayer(source)Jeśli zasób nie działa, FiveM drukuje No such export. Jeśli działa, ale nazwa eksportu jest zła, możesz skończyć z nil polem. Uruchom zasób pierwszy w server.cfg i sprawdź dokładne nazwy eksportów w jego dokumentacji lub fxmanifest.lua. Dwie powiązane poprawki: ESX jest nil i Brak takiego eksportu getSharedObject.
4. Dwukropek versus kropka
Dwukropek przechodzi obiekt jako ukryty pierwszy argument. Kropka nie. Mieszanie ich daje либо ten błąd, либо złe argumenty.
-- calls the method with the object as first argument
player:Notify('hello')
-- calls a plain function stored in a table
Utils.Notify('hello')Jeśli błąd mówi (method 'Notify'), obiekt nie ma wpisu Notify: użyj formy z kropką, jeśli funkcja żyje w tabeli biblioteki, lub sprawdź, czy obiekt naprawdę jest tym, co myślisz. Z ox_lib, na przykład, lib.notify({...}) to wezwanie z kropką w tabeli lib.
5. Funkcja jest zdefiniowana później lub w innym pliku
Lokalna funkcja musi być zdefiniowana przed linią, która ją wołuje, w tym samym pliku. Funkcja zdefiniowana w innym pliku jest tylko widoczna, jeśli jest globalna, i tylko jeśli ten plik jest ładowany przez tę samą stronę (klient lub serwer) tego samego zasobu.
-- fails: DoThing is defined below the call
DoThing()
local function DoThing()
print('hi')
endPrzenieś definicję powyżej wezwania, lub zadeklaruj to najpierw za pomocą local DoThing i przypisz później. Sprawdź też fxmanifest.lua: plik, który nie jest wymieniony w client_scripts, server_scripts lub shared_scripts, nigdy się nie ładuje, więc jego funkcje nigdy nie istnieją.
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }
shared_scripts { '@ox_lib/init.lua', 'config.lua' }6. Funkcja klienta używana na serwerze, lub odwrotnie
Wiele natives i funkcji frameworku istnieje tylko po jednej stronie. PlayerPedId jest tylko klientem, a GetPlayerIdentifiers jest tylko serwerem. Tabele frameworku również się różnią: ESX.GetPlayerFromId to funkcja serwera, podczas gdy klient używa ESX.GetPlayerData. Skrypt, który działa w shared_scripts, działa po obu stronach, więc wezwanie, które działa po jednej stronie, spada na drugiej.
Porada: najszybszym testem jest print zaraz przed linią niepowodzenia:
print(type(ESX.GetPlayerFromId)). Jeśli wypisujenil, funkcja brakuje. Jeśli wypisujefunction, prawdziwy problem jest gdzieś indziej.
Osłoń to, gdy debugujesz
Sprawdzaj, zanim wołasz, abyś otrzymał jasną wiadomość zamiast awarii:
local fn = ESX.GetPlayerFromId
if type(fn) ~= 'function' then
print('GetPlayerFromId is missing: check the ESX version')
return
endNie pozostawiaj straży, takie jak to, na miejscu jako naprawa. Ukrywają prawdziwy problem, którym jest skrypt i framework, które się nie pasują.
Lista kontrolna
| Objaw | Naprawa |
|---|---|
(global 'X') |
Funkcja nie jest zdefiniowana w pliku lub nigdy się nie załadowała: sprawdź manifest i kolejność definicji |
(field 'X') |
Tabela nie ma takiego wpisu: sprawdź pisownię i wersję frameworku |
(method 'X') |
Zły obiekt lub dwukropek użyty zamiast kropki: sprawdź, co zawiera zmienna |
| Działa tylko po jednej stronie | Funkcja istnieje tylko na kliencie lub tylko na serwerze |
| Błąd po aktualizacji frameworku | Zastąp usuniętą funkcję nową, lub zaktualizuj skrypt |
| Wezwanie eksportu zwraca nil | Uruchom dostarczający zasób pierwszy i sprawdź nazwę eksportu |
Szybkie odpowiedzi
Co oznacza 'attempt to call a nil value'?
Skrypt próbował uruchomić coś jako funkcję, ale nazwa zawiera nil, więc nie ma niczego do uruchomienia. Nazwa wewnątrz nawiasów mówi ci, której funkcji brakuje.
Jaka jest różnica między field, global i method w tym błędzie?
Global to sama nazwa, taka jak Foo(), field to wpis tabeli, taki jak Config.Foo() lub ESX.Foo(), a method to wezwanie z dwukropkiem, takie jak obj:Foo(). To tylko mówi ci, jak brakująca funkcja została osiągnięta.
Czy zła wersja frameworku może to spowodować?
Tak. Skrypt napisany dla starszej lub nowszej ESX, QBCore lub QBox może wywoływać funkcję, którą twoja wersja zmieniła nazwę lub usunęła, co pozostawia nil za sobą.
Skrypty bez tego problemu
Advanced BoostingBoosting pojazdów z tabletu: kontrakty od klasy D do S+, ekipy i kolejka na żywo.Zobacz skrypt →
Quest CreatorWizualny edytor questów i dialogów z NPC, budowanych węzeł po węźle w grze.Zobacz skrypt →
Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →