Hi,

I'm struggling with this one. In my 2D platformer, I have an enemy that I'd like to spawn a few seconds after the player spawns. I've been trying to do it with a SceneTree timer, but maybe I'm wrong about where to place this in my enemy's code.

Here's the relevant code:

func _ready():
	rng.randomize()
	position = startpos
	start_delay()
	$Timer.start()
	$AnimatedSprite.play()
 
func start_delay():
	rng.randomize()
	var waitstart = rng.randf_range(3.0, 6.25)
	print (waitstart)
	yield(get_tree().create_timer(waitstart), "timeout")

So I've created a start_delay() function that should pause a random amount of time between 3 and 6.25 seconds, and inserted it into func _ready(). Ignore the $Timer.start() line (it's referring to another timer used later for the enemy's movement).

What's happening is that my enemy is still spawning in at the start of the level with everything else. Is there a way to make this delay happen inside the enemy's code, or will I have to write it into the code for each level?

Thanks in advance for any light you can shed!

I am not 100% sure if this is the case or not, but I believe the yield statement only stops the execution of the function for a bit, so it is yielding the start_delay function but not the _ready function. I think if you use something like this, it should fix the issue:

func _ready():
	rng.randomize();
	position = startpos
	print ("Starting yield...")
	yield(get_tree().create_timer(get_delay_time()), "timeout")
	print ("Yield finished!")
	$Timer.start()
	$AnimatedSprite.play()

func get_delay_time():
	rng.randomize()
	var waitstart = rng.randf_range(3.0, 6.25)
	print (waitstart)
	return waitstart

@TwistedTwigleg thanks for the reply. I replaced mine with yours, and it still behaves as before. The "starting yield...", the yield time and "yield finished!" are printing at the right times, but the script continues to execute without actually yielding.

I'm able to delay the spawning of the enemy using a script attached to the level, which looks like this:

extends Node2D

var rng = RandomNumberGenerator.new()
var LocalPlopMan = preload("res://Scenes/PlopMan.tscn")


func _ready():
#	pass
	rng.randomize()
	var waitstart = rng.randf_range(3.0, 6.25)
	print (waitstart)
	yield(get_tree().create_timer(waitstart), "timeout")
	var LocalPlopManInstance = LocalPlopMan.instance()
	self.add_child(LocalPlopManInstance)

And this may be a better way to achieve the delay for some reasons, but since I'm then instancing the enemy in code, I lose the ability to visually position him in the editor (which may be a worthwhile tradeoff).

2 years later