attempt to call a nil value (field, global, method): come ripararlo
Ottenendo 'attempt to call a nil value' in FiveM? Cosa significano le varianti field, global e method, e come riparare un errore di digitazione, un'esportazione mancante o un errore colon-versus-dot.
Nella console:
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 ti dice che una riga ha provato a eseguire una funzione che non esiste. Questo articolo spiega le tre varianti, le solite cause, e come risolvere ognuna.
Cosa significa l'errore
In Lua un nome mancante non è un errore di per sé: leggerlo dà nil. L'errore appare solo quando metti le parentesi dopo, perché non puoi eseguire nil. Il testo tra le parentesi dice come lo script ha raggiunto la funzione mancante:
attempt to call a nil value (global 'X'): una chiamata semplice comeX(). La funzione non è definita da nessuna parte lo script possa vedere.attempt to call a nil value (field 'X'): una chiamata attraverso una tabella comeESX.X()oQBCore.Functions.X(). La tabella esiste, ma non ha alcuna voce denominataX.attempt to call a nil value (method 'X'): una chiamata con una virgola comeobj:X(). L'oggetto esiste, ma non ha alcun metodoX.
Il file e la riga davanti al messaggio (@my_script/server/main.lua:42) è la riga che fa la chiamata. Se non sei sicuro di come leggere il resto dell'output, vedi how to read a FiveM script error.
1. Un errore di digitazione nel nome
Lua è sensibile alle maiuscole. GetPlayerFromId e getPlayerFromId sono due nomi diversi, così come TriggerClientEvent e TriggerclientEvent. Confronta il nome nell'errore con la documentazione del framework, lettera per lettera.
2. La funzione non esiste nella tua versione
I framework rinominano e rimuovono le funzioni. Questa è la causa più comune su script scritti per un'altra versione del tuo framework.
-- an old call that may be gone on your version
local xPlayer = ESX.GetPlayerFromId(source)
xPlayer.getInventoryItem('bread')Controlla cosa offre davvero il tuo framework. Stampa la tabella per vedere le sue voci:
for name, value in pairs(ESX) do
print(name, type(value))
endSe la funzione che hai bisogno non è nell'elenco, lo script e il framework non corrispondono. Aggiorna il framework, aggiorna lo script, o sostituisci la chiamata con quella che la tua versione ha.
3. L'esportazione è mancante
Le esportazioni sono funzioni che un'altra risorsa fornisce. Quando la risorsa è interrotta, non si è avviata, o non esporta quel nome, la chiamata fallisce.
local core = exports['qb-core']:GetCoreObject()
core.Functions.GetPlayer(source)Se la risorsa non è in esecuzione, FiveM stampa No such export al contrario. Se è in esecuzione ma il nome di esportazione è sbagliato, potresti finire con un field nil. Avvia la risorsa per prima in server.cfg, e controlla i nomi di esportazione esatti nella sua documentazione o fxmanifest.lua. Due correzioni correlate: ESX is nil e No such export getSharedObject.
4. Colon versus dot
Una virgola passa l'oggetto come primo argomento nascosto. Un punto non lo fa. Mescolarli dà questo errore o argomenti sbagliati.
-- calls the method with the object as first argument
player:Notify('hello')
-- calls a plain function stored in a table
Utils.Notify('hello')Se l'errore dice (method 'Notify'), l'oggetto non ha alcuna voce Notify: usa la forma con il punto se la funzione vive sulla tabella della libreria, o controlla che l'oggetto sia davvero la cosa che credi. Con ox_lib, ad esempio, lib.notify({...}) è una chiamata con il punto sulla tabella lib.
5. La funzione è definita dopo o in un altro file
Una funzione locale deve essere definita prima della riga che la chiama, nello stesso file. Una funzione definita in un altro file è visibile solo se è globale, e solo se quel file è caricato dallo stesso lato (client o server) della stessa risorsa.
-- fails: DoThing is defined below the call
DoThing()
local function DoThing()
print('hi')
endSposta la definizione sopra la chiamata, o dichiara prima con local DoThing e assegnala in seguito. Controlla fxmanifest.lua anche: un file che non è elencato in client_scripts, server_scripts o shared_scripts non si carica mai, quindi le sue funzioni non esistono mai.
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }
shared_scripts { '@ox_lib/init.lua', 'config.lua' }6. Una funzione client usata sul server, o al contrario
Molti nativi e funzioni framework esistono solo su un lato. PlayerPedId è solo client, e GetPlayerIdentifiers è solo server. Le tabelle framework differiscono anche: ESX.GetPlayerFromId è una funzione server, mentre il client usa ESX.GetPlayerData. Uno script che viene eseguito in shared_scripts viene eseguito su entrambi i lati, quindi una chiamata che funziona su un lato si arresta sull'altro.
Consiglio: il test più veloce è un print proprio prima della riga che fallisce:
print(type(ESX.GetPlayerFromId)). Se stampanil, la funzione è mancante. Se stampafunction, il vero problema è da qualche altra parte.
Proteggilo mentre fai il debug
Controlla prima di chiamare, in modo da ottenere un messaggio chiaro invece di un arresto anomalo:
local fn = ESX.GetPlayerFromId
if type(fn) ~= 'function' then
print('GetPlayerFromId is missing: check the ESX version')
return
endNon lasciare protezioni come questa in posizione come correzione. Nascondono il vero problema, che è uno script e un framework che non corrispondono.
Elenco di controllo
| Sintomo | Correzione |
|---|---|
(global 'X') |
La funzione non è definita nel file o mai caricata: controlla il manifest e l'ordine di definizione |
(field 'X') |
La tabella non ha tale voce: controlla l'ortografia e la versione del framework |
(method 'X') |
Oggetto sbagliato o virgola usata al posto di un punto: controlla cosa contiene la variabile |
| Funziona solo su un lato | La funzione esiste solo su client o solo su server |
| Errore dopo un aggiornamento di framework | Sostituisci la funzione rimossa con quella nuova, o aggiorna lo script |
| La chiamata di esportazione restituisce nil | Avvia la risorsa che fornisce per prima e controlla il nome di esportazione |
Risposte rapide
Cosa significa 'attempt to call a nil value'?
Lo script ha provato a eseguire qualcosa come una funzione, ma il nome contiene nil, quindi non c'è nulla da eseguire. Il nome tra le parentesi ti dice quale funzione manca.
Qual è la differenza tra field, global e method in questo errore?
Un global è un nome semplice come Foo(), un field è una voce di tabella come Config.Foo() o ESX.Foo(), e un method è una chiamata con una virgola come obj:Foo(). Dice solo come la funzione mancante è stata raggiunta.
Una versione di framework errata può causarla?
Sì. Uno script scritto per una versione più vecchia o più recente di ESX, QBCore o QBox potrebbe chiamare una funzione che la tua versione ha rinominato o rimosso, il che lascia nil dietro.
Script senza questo problema
Advanced BoostingBoosting di veicoli dal tablet: contratti dalla classe D alla S+, crew e coda in tempo reale.Vedi script →
Quest CreatorUn editor visuale di missioni e dialoghi con gli NPC, costruito nodo per nodo in gioco.Vedi script →
Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →