On_timer_timeout() not working with if target

Everything works until 11:46 of the video.

Adding if target to the _on_timer_timeout() below doesn’t shoot projectiles…


@onready var turret_top: MeshInstance3D = $TurretBase/TurretTop

@export var projectile: PackedScene
var enemy_path: Path3D
var target: PathFollow3D

func _physics_process(delta: float) -> void:
	var target = find_best_target()
	if target:
		look_at(target.global_position, Vector3.UP, true)

func _on_timer_timeout() -> void:
	if target:
		var shot = projectile.instantiate()
		add_child(shot)
		shot.global_position = turret_top.global_position
		shot.direction = global_basis.z

func find_best_target() -> PathFollow3D:
	var best_target = null
	var best_progress = 0
	for enemy in enemy_path.get_children():
		if enemy is PathFollow3D:
			if enemy.progress > best_progress:
				best_progress = enemy.progress 
				best_target = enemy
	return best_target

Hi Walid,

It looks like there is a mistake in your code in the _on_timer_timeout function.
The last line in the method is missing the transform after global so it should read as below

shot.direction = global_transform_basis.z

This should get the code working again as it wouldnt correctly know the shot direction.

Let me know if this solves the issue.

Marc thank you for always answering all my questions so promptly and patiently.

You were absolutely right.

1 Like

I’m sorry to bug you again, Marc.

Fixing to global_transform.basis.z did not fix the issue.

even printing:

if target:
          print(target)

does not return anything. I think the issue is with identifying target. Possibly from the find_best_target function? Your help would be 100% appreciated.

Hi Walid,

I think the issue is probably in the structure in the heirarchy.
The for loop iterates through the path3d node finding the children which are our enemies.
If its not finding them because they are not a child of the path3d node then it will return as null.

Firstly
Double check that your enemies are a child of the path3d node in the editor.
If they are then in the _physics_process under the var target line print the target and see if it returns anything or it returns null.

Let me know how you get on as the only other thing i can think of is that your enemies are not PathFollow3D nodes and so its falling down at that point.

OMG I figured it out, and it was the dumbest reason ever!

var target: PathFollow3D

func _physics_process(delta: float) -> void:
	var target = find_best_target()
	if target:
		look_at(target.global_position, Vector3.UP, true)

The problem was that I defined var target again in the func _physics_process

Correct code:

func _physics_process(delta: float) -> void:
	target = find_best_target()
	if target:
		look_at(target.global_position, Vector3.UP, true)

Ugh that was so frustrating! What’s the best way to check against this happening again? Any good practice measures to avoid wrong variable scopes?

1 Like

Nice job finding that, Even i missed that one!
Unfortunately the intellisense would not help here as from its point of view there is nothing wrong with the code but it just have undesired effects.
In this case it is just look and find it using the print statements have we have to find where the code breaks down and causes an issue.

Really well done on following up with this and apologies that i missed that too!

I did the exact same and was wracking my brain over it, thanks!

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

Privacy & Terms