2
\$\begingroup\$

I have an object that needs to follow various Path2D paths in my scene. To do this, when it needs to follow a path, I re-parent it to a PathFollow2D that will traverse the relevant path. The code to do this looks like this:

# Remove from the current parent first, otherwise we can't set new parent
character.get_parent().remove_child(character)
slide_follow.add_child(character)

# ...set PathFollow2D in motion, etc...

Functionally, this works, and it's perfectly fine 90% of the time. However, because I have to remove the node from it's current/prior parent in order to add it, it briefly loses it's location and then comes back. Sometimes, this happens inside an Area2D that has collision detection on for the character, which results in body_exited and body_entered signals firing incorrectly unnecessarily, which can have adverse side effects.

I've tried temporarily disabling collision on the character to prevent this:

character.get_node("CollisionShape2D").disable = true
print("#1 removing from old parent")
character.get_parent().remove_child(character)
print("#2 parentless node")
slide_follow.add_child(character)
print("#3 on to new parent")
character.get_node("CollisionShape2D").disable = false

but the signals still fire:

#1 removing from old parent
exit signal fired!
#2 parentless node
enter signal fired!
#3 on to new parent

Is there a way to either keep the node in place or temporarily disable relevant collision so that the enter/exit signals don't fire during the reparenting process?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The node should keep its global position while it is out of the scene tree. The problem is not that it lost its position, the problem is that it is out of the scene tree. And there is no way to change the parent node without removing it from the scene tree and adding it back.


Shy of suggesting to write the path following code yourself so that it does not require to change parent nodes…

For non physics objects, I suggest to use a RemoteTransform2D to push the transform from the PathFollow2D to it (By making the RemoteTransform2D a child of the PathFollow2D, and setting its remote_path to the Node2D you want to control).

For a physics objects, however, I'd suggest to write code to follow the PathFollow2D. For example, a KinematicBody2D could do something like this:

func _physics_process(delta:float) -> void:
    # …
    if is_instance_valid(follow):
        global_rotation = follow.global_rotation
        move_and_slide((follow.global_position - global_position) / delta)

Where follow is a reference to the node currently being followed (e.g. the PathFollow2D).

\$\endgroup\$
1
  • \$\begingroup\$ Genius! Send the childless path sampler on its merry way, and just keep moving towards it while remaining a child of the actual parent scene. The documentation as well as tutorials all suggest (or outright say) a node must be a child node of a PathFollow2D in order to follow the path. Didn't even consider that it wasn't necessary. \$\endgroup\$
    – yoozer8
    Commented Jan 28, 2022 at 4:43

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .