Probem freeing objects from a level on scene change (like coins, pickups etc.)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By r3tr0_dev

I’m trying to make a simple platformer game in Godot, i have already made a player and I have a way to switch scenes (or levels) on the fly using Godot get_tree().change_scene() function since every level is a different scene with the Player, Tilemap and some TeleportZones for going from one level to another. I have a Global Autoload with an array for storing coins picked up by the player and his points var coins = [] and a Coin scene which is an Area2D node with this code here:

func _on_Coin_body_entered(body):
    if body.is_in_group("Player"):
	     Global.coins.append(name)
	     Global.points += 1
	     queue_free()

Then to free the Coins from the level i have a script attached to every Level node wich does the following:

func _ready():
    #For every Coin in Global.coins array, free them
    if Global.coins:
	    for i in Global.coins:
		    var coin = find_node(i)

		    if !coin:
			    return
		
		    coin.queue_free()

But for some strange reasons, if i pick up Coins in Level 1 and go to Level 2 then back Coins do not reload like intended BUT if I pick up Coins in Level 1 first and then I pick up Coins in Level 2 and go back to Level 1 the Coins from the first level are freed but when going back to Level 2 the Coins from the second level are not. I already checked and the Coins.name is stored inside the global array when the level is ready. It seems like a problem in the for cycle inside the _ready() function of the levels but i don’t know what could be the problem, maybe the cycle isn’t ending?

P.S.: Sorry for my bad English but it’s not my main language since I’m Italian

:bust_in_silhouette: Reply From: jgodfrey

I’m struggling a bit to follow what you’re trying to accomplish, but that return in your ready function looks problematic to me, here:

        if !coin:
            return
        coin.queue_free()

If the current coin doesn’t exist, that’ll cause you to stop checking for the other coins in the array. I’d guess you may want this instead:

        if !coin:
            continue
        coin.queue_free()

Or, even better:

        if coin:
            coin.queue_free()

I can’t believe that was so simple, I didn’t realise that if I return the for-loop it didn’t check for the other coins in the array. Thanks.

r3tr0_dev | 2020-12-09 10:44