-
-
Notifications
You must be signed in to change notification settings - Fork 21.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reparenting node in Area.body_entered causes crash #34207
Comments
|
Me too. The newly added body is detected again and enters a loop. This is weird though. Using add_child inside signals should be disallowed. I had an error about this multiple times, but it doesn't seem to be triggered here, |
The cause of the crash seems to be the mentioned stack overflow (#34207 (comment) , #34207 (comment)). As mentioned above,
I disagree and I don't think this is a bug, because there are easy solutions for the Game Developer to fix this. One for this particular example would be a short check, if the bodys parent is the area2d func on_body_entered(body: Node):
if(body.get_parent() != self):
body.get_parent().remove_child(body)
add_child(body) Another reason why I think this is expected behaviour is that it might be even useful to trigger this event for new created bodies. Example (Pseudocode): func on_unit_entered(unit: Node):
if(unit.type == "commander"):
add_child(unit_tank)
add_child(unit_soldier)
add_child(unit_soldier)
reinforcements_received = true
units_in_area += 1
if(units_in_area > 10):
trigger_event(EVENT_SPAWN_ENEMY_TROUPS);
disconnect("body_entered", self, "on_unit_entered") Edit: The only thing I can think of is |
Adding another test project that I believe is related, but shows some interesting differences. This was tested with
## CHOOSE ONLY ONE OF THESE PICKUP METHODS
## - picking up by area_entered signal will crash when re-added
## - picking up by timeout signal will *NOT* crash when re-added
# get_node("Character/PickupArea").connect("area_entered", self, "pickup_item")
get_node("PickupTimer").connect("timeout", self, "pickup_item", [ get_node("AreaItem") ])
|
I'm getting this on 3.2.3 stable. In my case, add_child is called later in the stack inside a different function. The stack starts with a body_entered signal and using call_deferred as suggested by @rcorre doesn't work. I disagree that adding children from a signal should be disallowed as suggested by @KoBeWi , even though there's a good explanation for the issue it can still be solved within the engine. A game developer or light script user shouldn't have to worry about engine threads, an engine developer should. |
Did some testing:
@rcorre's MRP ported to |
Just run into this, confirmed still occurring in From my testing, deferring the |
Godot version:
OS/device including version:
Issue description:
If you reparent a
Node
while handling theArea.body_entered
signal, godot crashes.My use case was an object that can "grab" another object like a magnet.
Steps to reproduce:
Area
with this script:KinematicBody
into the areaI can try to repro with debug bits if desired.
Minimal reproduction project:
example.zip
The text was updated successfully, but these errors were encountered: