About await and loops fails

Godot Version

4.3 estable

Question

Hello, I have been having trouble using the await statement within a loop, as the iterative variables get reset every time the await statement is reached. I wonder, how could I prevent iterative variables from resetting every time await is used? Is there any way to simulate await without using it?

Paste a code sample, await should be usable within a loop, maybe you are calling the loop multiple times?

1 Like

func start_movement(cant_pasos: int):
var direction
var next_position
var next_path_position
var curve = player.get_parent().get_parent().curve
var baked_points = curve.get_baked_points()
var current_position = player.get_parent().position
var closest_offset = curve.get_closest_offset(current_position)
var next_offset = closest_offset + (0.01 * curve.get_baked_length())
var current_path_offsets = get_path_offsets(player.get_parent()).size()
aux = 0
while aux < cant_pasos:
#la i se esta volviendo 0 en cada iteracion, revisar
if aux == cant_pasos:
stop_movement()
is_moving = true
if player_pos + 1 < current_path_offsets:
next_position = get_path_offsets(player.get_parent())[player_pos + 1]
while current_position.distance_to(next_position) > 1.0: # Add tolerance to prevent infinite loop
if current_position == next_position:
break
curve = player.get_parent().get_parent().curve
# Obtener la posición actual y la siguiente posición en la curva para calcular la dirección
current_position = player.get_parent().position
closest_offset = curve.get_closest_offset(current_position)
next_offset = closest_offset + (0.01 * curve.get_baked_length())
baked_points = curve.get_baked_points()
var baked_points_size = baked_points.size()
var index = int(next_offset * baked_points_size / curve.get_baked_length())

			if index >= 0 and index < baked_points_size: 
					next_position = baked_points[int(next_offset * baked_points.size() / curve.get_baked_length())]
					direction = (next_position - current_position).normalized()
					player.play_animation(direction)
					is_moving = true
			else: 
				stop_movement()
			
		is_moving = false
		player_pos += 1
		aux += 1
	else: 
		stop_movement()
		return

the problem is with aux var

What happens? What do you expect to happen? Make sure to paste with code formatting so everyone can read it.

2 Likes

With the code, I am trying to make a character walk across a board, using a roulette to advance. The type of game would be similar to Monopoly or Mario Party.

extends Node2D
#variables comunes
@onready var player = $wrong_Path2D1/wrong_path1/Elenmayer
#referencia al jugador
@onready var path2d = player.get_parent()
@onready var correct_path_follow = $correct_Path2D/correct_path
@onready var wrong_path_follow1 = $wrong_Path2D1/wrong_path1
@onready var wrong_path_follow2 = $wrong_Path2D2/wrong_path2
@onready var wrong_path_follow3 = $wrong_Path2D3/wrong_path3
@onready var wrong_path_follow4 = $wrong_Path2D4/wrong_path4
#referencia a los diferentes pathfollows del nivel
@onready var player_anim = player._get_anim_player()
var is_moving = false

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	GLOBAL.rutaLvl = "res://Scenes/nivel_3.tscn"


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	if is_moving:
		_move_along_the_path(delta)
	else:
		stop_movement()


#Botones------------------------------------------------------------------
func _on_sound_btn_pressed() -> void:
	if $Musica.playing == true:
		$Musica.stop()
	else:
		$Musica.play()


func _on_home_btn_pressed() -> void:
	get_tree().change_scene_to_file("res://Scenes/niveles.tscn")


func _on_help_btn_pressed() -> void:
	pass # Replace with function body.


func _on_info_btn_pressed() -> void:
	pass # Replace with function body.


func _on_retry_btn_pressed() -> void:
	get_tree().change_scene_to_file("res://Scenes/nivel_3.tscn")


func _on_consulta_btn_pressed() -> void:
	get_tree().change_scene_to_file("res://Scenes/consulta.tscn")


#Funciones de movimiento-----------------------------------------------
func _move_along_the_path(delta):
	player.get_parent().progress_ratio += 0.05 * delta
	if correct_path_follow.progress_ratio >= 1.0:
		stop_movement()

@onready var correct_path_offsets = get_path_offsets(player.get_parent().get_parent())
@onready var total_points = correct_path_offsets.size()
func get_path_offsets(path2D):
	var curve = player.get_parent().get_parent().curve
	var path_offsets: Dictionary
	for i in range(curve.get_point_count()):
		var point_pos = curve.get_point_position(i)
		path_offsets[i] = point_pos
	return path_offsets

var aux = 0
var player_pos = 0
#para mover a traves de las llaves del diccionario path_offsets

#func start_movement(cant_pasos: int):
	#var direction
	#var next_position
	#var next_path_position
	#var curve = player.get_parent().get_parent().curve
	#var baked_points = curve.get_baked_points()
	#var current_position = player.get_parent().position
	#var closest_offset = curve.get_closest_offset(current_position)
	#var next_offset = closest_offset + (0.01 * curve.get_baked_length())
	#var current_path_offsets = get_path_offsets(player.get_parent()).size()
	#aux = 0
	#while aux < cant_pasos:
		##la i se esta volviendo 0 en cada iteracion, revisar
		#if aux == cant_pasos: 
			#stop_movement()
		#is_moving = true
		#if player_pos + 1 < current_path_offsets:
			#next_position = get_path_offsets(player.get_parent())[player_pos + 1]
			#while current_position.distance_to(next_position) > 1.0:  # Add tolerance to prevent infinite loop
				#if current_position == next_position:
					#break
				#curve = player.get_parent().get_parent().curve
	## Obtener la posición actual y la siguiente posición en la curva para calcular la dirección
				#current_position = player.get_parent().position
				#closest_offset = curve.get_closest_offset(current_position)
				#next_offset = closest_offset + (0.01 * curve.get_baked_length())
				#baked_points = curve.get_baked_points()
				#var baked_points_size = baked_points.size()
				#var index = int(next_offset * baked_points_size / curve.get_baked_length())
	#
				#if index >= 0 and index < baked_points_size: 
						#next_position = baked_points[int(next_offset * baked_points.size() / curve.get_baked_length())]
						#direction = (next_position - current_position).normalized()
						#player.play_animation(direction)
						#is_moving = true
				#else: 
					#stop_movement()
				#
			#is_moving = false
			#player_pos += 1
			#aux += 1
		#else: 
			#stop_movement()
			#return
		#


func start_movement(cant_pasos: int):
	var direction
	var next_position
	var curve = player.get_parent().get_parent().curve
	# Obtener la posición actual y la siguiente posición en la curva para calcular la dirección
	var current_position = player.get_parent().position
	var closest_offset = curve.get_closest_offset(current_position)
	var next_offset = closest_offset + (0.01 * curve.get_baked_length())
	var baked_points = curve.get_baked_points()
	var baked_points_size = baked_points.size()
	var index = int(next_offset * baked_points_size / curve.get_baked_length())
	
	if index >= 0 and index < baked_points_size: 
		next_position = baked_points[int(next_offset * baked_points.size() / curve.get_baked_length())]
		direction = (next_position - current_position).normalized()
		player.play_animation(direction)
		is_moving = true
	else: 
		stop_movement()

func stop_movement():
	player_anim.stop()
	#detiene la animacion de caminar
	is_moving = false

func playRun():
	start_movement($Fondo/Ruleta.cant_pasos)

this is the entire script, they are two differents ways of movement, one of them the comented one, with that one, i can go across the pathfollow2d, but there is no stop by the number of steps with that one

when the other start_movement is used, the no comented one, the var aux doesnt get updated when the loop goes to the beginin again… in debug I noted that the await instruction makes var aux 0 again, so, the loop fails and the code doesnt work :sweat_smile:

There is no await instruction in your paste, can you point out what you are talking about?

1 Like

you are absolutly right, my bad, this is another code…
this is the actual code

extends Node2D
#var playerRun = 0
#var playerPos = 0
#var globPos = [428, 202]#posicion de inicio del camino a seguir
#@onready var player = $correct_Path2D/correct_path/Elenmayer
@onready var player = $wrong_Path2D1/wrong_path1/Elenmayer
#referencia al jugador
@onready var path2d = player.get_parent()

@onready var correct_path_follow = $correct_Path2D/correct_path
@onready var wrong_path_follow1 = $wrong_Path2D1/wrong_path1
@onready var wrong_path_follow2 = $wrong_Path2D2/wrong_path2
@onready var wrong_path_follow3 = $wrong_Path2D3/wrong_path3
@onready var wrong_path_follow4 = $wrong_Path2D4/wrong_path4
#referencia a los diferentes pathfollows del nivel

@onready var player_anim = player._get_anim_player()
#si esto no funciona asi, tendre que anhadir el nodo animation player del personaje como hijo del mismo en cada nivel
#referencia al animation player del jugador
var is_moving = false

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	GLOBAL.rutaLvl = "res://Scenes/nivel_3.tscn"


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
	if is_moving:
		_move_along_the_path(delta)
	else:
		stop_movement()

func _move_along_the_path(delta):
	player.get_parent().progress_ratio += 0.05 * delta
	if correct_path_follow.progress_ratio >= 1.0:
		stop_movement()

@onready var correct_path_offsets = get_path_offsets(player.get_parent().get_parent())
@onready var total_points = correct_path_offsets.size()
func get_path_offsets(path2D):
	var curve = player.get_parent().get_parent().curve
	var path_offsets: Dictionary
	for i in range(curve.get_point_count()):
		var point_pos = curve.get_point_position(i)
		path_offsets[i] = point_pos
	return path_offsets

var player_pos = 0
#para mover a traves de las llaves del diccionario path_offsets
func start_movement(cant_pasos: int):
	var direction
	var next_position
	var curve = player.get_parent().get_parent().curve
	var baked_points = curve.get_baked_points()
	var current_position = player.get_parent().position
	var closest_offset = curve.get_closest_offset(current_position)
	var next_offset = closest_offset + (0.01 * curve.get_baked_length())
	var current_path_offsets = get_path_offsets(player.get_parent()).size()
	
	for i in range (cant_pasos):
		if i>=cant_pasos:
			break
		else:
			if player_pos + 1 < current_path_offsets:
			
				next_position = get_path_offsets(player.get_parent())[player_pos + 1]
				while current_position.distance_to(next_position) > 1.0:  # Add tolerance to prevent infinite loop
					current_position = player.global_position
					direction = (next_position - current_position).normalized()
					player.play_animation(direction)
					await get_tree().process_frame  # Await Frame
					is_moving = true
			
				player_pos += 1
			else: 
				stop_movement()
				return
		stop_movement()


#func start_movement(cant_pasos: int):
	#var direction
	#var next_position
	#var curve = player.get_parent().get_parent().curve
	## Obtener la posición actual y la siguiente posición en la curva para calcular la dirección
	#var current_position = player.get_parent().position
	#var closest_offset = curve.get_closest_offset(current_position)
	#var next_offset = closest_offset + (0.01 * curve.get_baked_length())
	#var baked_points = curve.get_baked_points()
	#var baked_points_size = baked_points.size()
	#var index = int(next_offset * baked_points_size / curve.get_baked_length())
	#
	#if index >= 0 and index < baked_points_size: 
		#next_position = baked_points[int(next_offset * baked_points.size() / curve.get_baked_length())]
		#direction = (next_position - current_position).normalized()
		#player.play_animation(direction)
		#is_moving = true
	#else: 
		#stop_movement()

func stop_movement():
	player_anim.stop()
	#detiene la animacion de caminar
	is_moving = false

func playRun():
	start_movement($Fondo/Ruleta.cant_pasos)

func _on_sound_btn_pressed() -> void:
	if $Musica.playing == true:
		$Musica.stop()
	else:
		$Musica.play()


func _on_home_btn_pressed() -> void:
	get_tree().change_scene_to_file("res://Scenes/niveles.tscn")


func _on_help_btn_pressed() -> void:
	pass # Replace with function body.


func _on_info_btn_pressed() -> void:
	pass # Replace with function body.


func _on_retry_btn_pressed() -> void:
	get_tree().change_scene_to_file("res://Scenes/nivel_3.tscn")


func _on_consulta_btn_pressed() -> void:
	get_tree().change_scene_to_file("res://Scenes/consulta.tscn")

I don’t see where playRun is being called, but this loop should be moved to a _process function, you want it to act every frame which is what _process is built for.

1 Like

thank you so much for your time and answers, i will try it, thanks again pal

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.