Help with queue_free() / remove_child(node)

Godot Version

4

Question

Sorry if this has been asked before. I am mostly new to video game dev stuff and am learning as I go. I’ve been playing around with instantiate() a bit and have come across that you are able to remove the child node once it’s added with either queue_free() or remove_child(node). I have not been able to get any of these to actually remove the instanced node from the screen once the trigger for it occurs.

For more details, the trigger spawns a sprite from a different scene - works fine, once the trigger to despawn it is met, I am generally faced with an error, specifically:

p_child->data.parent !=this

This error only occurs if I use remove.child(node), if I use queue_free() instead I don’t receive any errors, but neither does the sprite disappear.

Any help on this would be greatly appreciated. The idea is that if a character is a certain distance of the x axis, the trigger should happen, then if they move back, the spawned item should disappear. Sorry if I am missing something that should be inherently obvious.

The test code is as follows:

extends StaticBody2D
@onready var _animated_sprite = $AnimatedSprite2D
@onready var PlayerInfo = get_tree().get_first_node_in_group(“player”)
@onready var text_box_scene = load(“res://Box.tscn”)

var box_spawned = false
var box

func UpdateAnimation():
_animated_sprite.play(“Lant_Idle”)
box = text_box_scene.instantiate()

if PlayerInfo.global_position.x > global_position.x +20:
	$AnimatedSprite2D.flip_h = true
	
	box.global_position = PlayerInfo.global_position
	box.global_position.y = box.global_position.y -400
	
	if box_spawned == false:
		get_tree().root.add_child(box)
		box_spawned = true

	
elif PlayerInfo.global_position.x < global_position.x - 50:
	$AnimatedSprite2D.flip_h = false
	if box_spawned == true:
		box.queue_free()
		box_spawned = false

func _physics_process(_delta):
UpdateAnimation()

It’s possible that you would want to do something like this intead:

  1. Add an Area2D to the text_box_scene.
  2. Add a CollisionShape2D to the Area2D and make it a Box shape and make it the size around the box within which the player should be to show the box.
  3. Attach a script to the box scene, you can call it text_box.gd or whatever you prefer.
  4. On the Area2D connect the signals body_entered and body_exited (if your Player is a CharacterBody2D, otherwise area_entered)
  5. This is what you want in the script:
    text_box.gd
extends Sprite2D # or whatever node you are using

_ready():
  set_visible(false)

_on_body_entered(body):
  if body is Player:
    set_visible(true)

_on_body_exited(body):
  if body is Player:
    queue_free()

Make sure to add class_name Player to your player.gd

class_name Player extends CharacterBody2D # or whatever you are using

Instead of queue_free() you may want to use set_visible(false), if the box should be able to show again if the player is within distance.