James Garcia
James Garcia

Reputation: 11

Godot: Invalid call. Nonexistent function 'insert' in base 'Nil'

I get the error Nonexistent function 'insert' in base 'Nil' from this function

@export var inv: Inv

func collect(item):
    inv.insert(item)

The insert function is below:

extends Resource
class_name Inv
signal update
@export var slots: Array[InvSlot]

func insert(item: InvItem):
    var itemslots = slots.filter(func(slot): return slot.item == item)
    if !itemslots.is_empty():
        itemslots[0].amount += 1
    else:
        var emptyslots = slots.filter(func(slot): return slot.item == null)
        if !emptyslots.is_empty():
            emptyslots[0].item = item
            emptyslots[0].amount = 1
    update.emit()

The item being sent to the collect function is from:

@export var item: InvItem

func _on_collect_area_body_entered(body):
    if body.has_method("player"):
        player = body
        player.collect(item)
        #queue_free()

And finally InvItem is:

class_name InvItem

@export var name: String = ""
@export var texture: Texture2D

When I change collect() to print out item.name and item.texture i get "sword <CompressedTexture2D#-9223371997210213091>" which looks correct but it wont let me pass it through. I can't send anything to the Inv class, I have tried with different random parameters and a different function.

Upvotes: 1

Views: 1372

Answers (1)

Theraot
Theraot

Reputation: 40295

When Godot tells you

Nonexistent function '<name>' (...)

The problem is that Godot is unable to find the function. The arguments to the function are irrelevant if Godot cannot find the function.


Next Godot tells you where it was looking:

... (on base 'Nil')

The problem is that you are trying to access something that is not initialized.

You could address this directly by checking for null if x == null: #... Or use is_instance_valid if the type is not referene counted (e.g. Nodes). But that won't take you to the root of the problem: why is is it an invalid instance?

Make sure you are initializing whatever is it on you are trying to access.

  • It could be simply that you forgot to call the function where you initialize it.

  • Or it could be that the initialization gets called, but your code is running before that. For example, you might be intializing it on ready, but your code is running before ready. For this case you might want to check is_node_ready.

  • Or it couild be an exported variable, that you forgot to set in the inspector.

    If you need help preventing the case where you didn't initialize your export variable, consider creating a configuration warning could alert you of the issue (it requires @tool).

See also When are @export values set?


In the question at hand, the problem is that you are trying to call insert on an uninitialized inv, which you - probably - didn't set in the inspector (or some other code removed it).

Upvotes: 0

Related Questions