#Reparenting node causes area2d exited signal

10 messages · Page 1 of 1 (latest)

hasty vault
#

Okay, so I've got some rigidbodies and I've got an area2d that detects when a body enters and exits.

If the rigidbody enters the area2d and exits the area2d it triggers the appropriate signals just fine everything is working. HOWEVER when I reparent the rigidbody while it is in the area2d it does something weird. It triggers the following signals in the following order: 1. exits 2. enters 3. exits again 4. it enters again.

What in the world is going on? lol I can come up with theories about why this is happening but I have no definitive answer. (and yes I have been trying to figure it out on my own for awhile and looked google + the docs)

I'm on godot 4.1 Windows.

#

here you can see what happens. the barrel enters the area2d and it prints the signal but when i press a button that reparents the barrel to a different scene than what it's in the area2d signals go nuts

shy aspen
#

Heya, did you perhaps find a workaround for this?

forest junco
#

Hi there 😊 (necrothread smile 💀),

The easy workaround is in the reddit thread. Adding a property (e.g. is_currently_reparented) on every item class the Area2D handles and set it to true on an object of this class before reparenting. In the callback on Area2D check for the property and if it's true don't run the callback (maybe resetting the property right in the callback).

However, this is unclean as every handled class must extend its interface now, which is a burden on the class developers. It would be better if the Area2D can do this with on-board functions of Godot for/by itself.

A more sophisticated (but complicated) version would be extending the Area2D to register itself to various scene related notifications (enter-tree, exit-tree, ...) (https://docs.godotengine.org/en/stable/tutorials/best_practices/godot_notifications.html#godot-notifications ) once an object of a class enters its area and keeps internal "tabs" on the objects and knows when the object is reparented and can skip running the callback than.

shy aspen
#

I did some testing - the is_currently_reparented solution isn't a good fit because I have multiple area2Ds overlapping.

#

And I'll try to do something with the notifications.

Wished there was a native solution 😦

wraith timber
#

May the .monitoring = false and .monitorable = false help you?

shy aspen
# forest junco Hi there 😊 (necrothread smile 💀), The easy workaround is in the reddit thread...

So I took the two suggestions and sort of combined them to a new idea:

Every Area2D can keep track on the parent of the node it's currently handling, and if the parent node is different from what it expects, update it and skip the call.

Tried to generalize the code a bit so it can fit others, but there are still some parts that are specific for my code.

var handled_nodes: Dictionary = {}

func _body_entered(body: Node2D) -> void:
    if not handled_nodes.has(body):
        print("Registering " + body.name)
        handled_nodes[body] = gravity_component.current_parent_node
    else:
        # If we receive "entered" signal again while we still have the node registered, we should ignore it because the node never really left
        print("Already registered " + body.name)
        return
        
        
func _body_exited(body: Node2D) -> void:
    if handled_nodes.has(body) and handled_nodes[body] != gravity_component.current_parent_node:
        print("Parent is different for " + body.name)
        handled_nodes[body] = gravity_component.current_parent_node
        return

    if atmosphere.get_overlapping_bodies().has(body):
        print("The node " + body.name + " is still in the area of " + self.name)
        return

It works well so far!

hasty vault
# shy aspen Heya, did you perhaps find a workaround for this?

I honestly can't remember even what the issue was with these signals going off. I ended up just reparenting it to the train and i believe that worked fine? but it's been so long. here is the repo if you're interested.

https://github.com/bonsaipropaganda/train-game

and the final "game"
https://bonsaipropaganda.itch.io/stack-the-stuff

GitHub

Contribute to bonsaipropaganda/train-game development by creating an account on GitHub.

itch.io

Stack the stuff as fast as you can