Why is this variable not being updated during a while loop?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Clearleaf
:warning: Old Version Published before Godot 3 was released.

I want my character to touch the top of an Area2D and then instantly pass through it. Another way to describe it would be that I want to teleport from above an Area2D to below it.

Here’s the bit of code where the problem occurs. I’ve edited it down to try to make what I’m doing more clear.

onready var Collisions = get_node("Area2D")
var ground_id = Collisions.get_overlapping_areas()[0]

while ground_id.a == "Foo":
    set_pos(get_pos() + Vector2(0,1))
	ground_id = Collisions.get_overlapping_areas()[0]

Basically if the player overlaps with an Area2D node that has a variable named ‘a’ set to “Foo”, I want to move the player down until it finds an Area2D with variable ‘a’ set to something other than “Foo”.

The problem is that once the loop is started, it never finds ‘a’ to be anything other than “Foo” so the loop runs forever, even if (I think) the Player comes to overlap an Area2D with ‘a’ set to “Bar” after having it’s position changed. If I code the loop to break after 100 iterations, then it will appear that set_pos() was successfully applied 100 times and I can continue moving around from the new position. If set_pos() is applied 100 times and the player is still overlapping an Area2D with an ‘a’ of “Foo”, then the loop will run again and set_pos() will be applied another 100 times. It never seems to detect a change until some point after the loop has finished and I have no idea why.

What is the massive misunderstanding that I’m having with how Godot does things like this?

:bust_in_silhouette: Reply From: eons

You are moving an area in a loop, inside a function, the physics server won’t update physics inside your loop, just once in each physics frame (and get_overlaping_bodies may need a few physic frames to detect something after the node containing the shape was moved).

To do what are you trying to do, use Physics2DDirectSpaceState or Shape2D methods for arbitrary overlap checks.

http://docs.godotengine.org/en/stable/classes/class_physics2ddirectspacestate.html

:bust_in_silhouette: Reply From: rredesigns

If I were to do that, I would just increase it’s position slowly downwards by about the floor’s Y scale plus a bunch of pixels.

Once that’s done I would stop changing the position and the physics will handle the rest as usual.