Invalid get index (on base: 'previously freed')

Godot Version

<stable4.2>

Question

<I am trying to access variable from node group in “enemies”. so that player can change its state when enemy finished certain state. However, i am receiving an error Invalid get index 'grab_finished' (on base: 'previously freed'). I am assuming that this error is caused because grab_finished = true is called while enemy is queued free. How can I solve this?

in enemy script:

States.DEATH:
			print("DEATH")
			grab_finished = true
			queue_free()

In player script:

@onready var enemy = get_tree().get_nodes_in_group("enemies")

In player state script:

func physics_update(delta: float) -> void:
	if player.enemy[0].grab_finished:
		print("grab_finished")

You can use is_instance_valid(object) to check if an object is valid(has not been freed) before performing any action on the object.

1 Like

thank you for the response. where should i put that line of code?

Before you access variables from the enemy.

func physics_update(delta: float) -> void:
     if is_instance_valid(player.enemy[0]):
          player.enemy[0].grab_finished:
          print("grab_finished")

now there is no error, yet “grab_finished” wont be printed

That is because, if the enemy has been queue freed (i.e not valid), the print(“grab_finished”) line won’t be reached.

how can i solve that problem ?

Not sure I understand your question. Is there any other problem you are trying to solve apart from the error caused by trying to access variable of a freed enemy?

im trying to access variable when enemy finished certain state.
when player hit the enemy, enemy will change its state to grab state, and when animation finished while in grab state, enemy will change its state to death state. I want to let player know when enemy finished grab state.

func _on_animation_player_animation_finished(anim_name):
	if anim_name == "finish":
		state = States.DEATH

but since enemy queue freed in States. DEATH. player cannot access variable of grab_finished = true.

This is a good use case for signals. Before freeing the enemy, you can emit a signal the player can receive so the player knows that the enemy jas finished its grab state. If you’re not used to reading signals, read up on it in the Godot docs.

Another option is that you just call a function directly in the player script from the enemy before it’s freed, this means you need a reference to the player in the enemy script.

Something like this before queue_free() is called:

player.enemy_grab_state_finished()

i was able to solve the problem by using signal. thank you very much

1 Like