Node3d.queue_free.call_deferred() throws error when calling upon area_enterrd

Godot Version

4.4.1 Stable

Question

I have a scene that has a node within. This node contains an Area3D node and I need to queue_free() the node upon receiving area_entered signal from Area3D.

The problem is when I try to do that I get an error that suggests using call_deferred() method for freeing a node.

I tried to use it like node3d.queue_free.call_deferred(), but there is no difference, I also tried to have await get_tree().physics_frame right before the call_deferred() but still get the error.

What is the proper way to queue_free a node that is Area3D or contains it upon receiving area_entered signal?

Here’s my current code:

@icon("res://addons/16x16_icons/arrow_raise.png")
class_name Effect
extends Node3D


@export var effect_data: EffectData
@export var trigger_area: Area3D
@export var view_3d: Node3D

func _ready() -> void:
	trigger_area.area_entered.connect(_on_area_entered)


func _on_area_entered(area: Area3D) -> void:
	var entity: Entity
	if area.owner is Entity:
		entity = area.owner
	elif area.owner is Bullet:
		var area_owner: Bullet = area.owner
		entity = area_owner.owner_parent
	call_deferred("remove_view_3d")
	reparent(entity.effect_manager)
	entity.effect_manager.add_effect(effect_data)


func remove_view_3d() -> void:
	await get_tree().process_frame
	view_3d.queue_free()

The error I’m getting:

E 0:00:06:176 Effect.gd:22 @ _on_area_entered(): Removing a CollisionObject node during a physics callback is not allowed and will cause undesired behavior. Remove with call_deferred() instead.
<C++ Source> scene/3d/physics/collision_object_3d.cpp:113 @ _notification()
Effect.gd:22 @ _on_area_entered()

Okay, nevermind it was reaparent() method that was also causing this issue

1 Like

Isn’t the error you are seeing for triggered for the reparent call?

Yeah I replied to my own post and maked it as a solution👍

Now I have to make a full circle in the future, when I’ll have the same problem and come to my own solution🫠

Yeah, sorry, I commented right after you posted, but my comment had to be approved by someone and they just got around to it. Glad you sorted it out.

For posterity, the “22” next to the class name in the error message is the actual line number. I counted the lines in your code snippet and voila, the call to reparent function was on line 22.

Cheers

2 Likes

Yeah, rookie mistake, I saw it but was in some unnecessary rush and didn’t notice it :sweat_smile:

Anyway you would be a lifesaver, so thank you!