Barbarian Blaster Issue With Dealing Damage

Hey everyone!

I’m working through the Godot 3D course and am stuck on the dealing damage lesson for Barbarian Blast. I think I have everything set up correctly, but when I test my game, my projectiles do not see any groups associated with my enemy Area3Ds. I’ve set up the group correctly in the editor and it shows up in the group manager tab, but when I have my projectile print out the groups it sees, it’s getting an empty array. Any ideas why this might be happening?

What I’m interpreting from this is that the projectiles are colliding and being freed properly, but they aren’t causing damage to the barbarians on hit.

Can you post your code and some screenshots of the Editor? It’s a bit difficult to discern more than that from the description alone =)

Really appreciate the help! I think I’m encountering 2 issues:

  1. It doesn’t appear like the game registers a collision every time the projectile hits an enemy.
  2. When it does, it’s still not identifying any groups being attached to the EnemyArea3D.

Including the turret code and projectile code as well as what I’m seeing in the editor

Projectile Code

extends Area3D

var direction := Vector3.FORWARD

@export var speed  := 30.0

func _physics_process(delta: float) -> void:
	position += direction * speed * delta
	


func _on_timer_timeout() -> void:
	queue_free() # Replace with function body.



func _on_area_entered(area: Area3D) -> void:
	printt(area.name,area.get_groups())
	if area.is_in_group('enemy_area'):
		area.get_parent().current_health -= 25
		queue_free() # Replace with function body.

Turret Code

extends Node3D

@export var projectile : PackedScene
@export var turret_range := 10.0

@onready var turret_top: MeshInstance3D = $TurretBase/TurretTop
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var barrel: MeshInstance3D = $TurretBase/TurretTop/Visor/Barrel
@onready var turret_base: MeshInstance3D = $TurretBase

var enemy_path : Path3D
var target : PathFollow3D

func _on_timer_timeout() -> void:
	if target:
		var shot = projectile.instantiate() 
		animation_player.play("fire")
		add_child(shot) # Replace with function body.
		shot.global_position = turret_base.global_position
		shot.direction = global_basis.z

func _physics_process(delta: float) -> void:
	target = find_best_target()
	
	if target:
		look_at(target.global_position, Vector3.UP, true)
 
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:
				var distance = global_position.distance_to(enemy.global_position)
				if distance <= turret_range:
					best_target = enemy
					best_progress = enemy.progress
	
	return best_target

enemy_editor_config

Sure! I’ll do what I can.

Regarding this, does the projectile still get deleted correctly when it hits an enemy?

I checked the curriculum and the instantiation doesn’t happen for another few lectures, so these are most likely manually-placed enemies. I wouldn’t be surprised if some/all of them are incorrectly synchronized with the actual object scene they are meant to instance from; this is a known problem, and somebody else had a very similar issue a week or two ago. The first thing I’ll suggest therefore is to delete all of your enemy instances and place new ones. This may or may not fix everything, so keep your test statements in place and let me know what the new findings are. We’ll go from there =)

Thanks! I tried replacing the enemies and had the same issue. I also kept going with the tutorial, hoping that the spawned enemies might behave differently but I got the same issue. I also tried to force the instantiated enemies to add the child EnemyArea3D node to the “enemy_area” group, but I’m still seeing an empty array for the node’s groups.

Hm! A stubborn issue, and it works the same way for me without any fuss. If you added the nodes to the group at runtime and you’re still seeing the same problem, there must be something deeper going on. The only other thing I can think of at the moment to look at would be to compare the console output names to the names in the Remote tab and ensure it’s actually checking the correct areas, but I can’t imagine what else would be there to interfere.

I’d also be curious to see if the same thing happens in reverse in your project. In my own project, for a reason that isn’t clear to me anymore (probably just cleanup that I didn’t get to), I also have code on the enemy that checks if the area is a projectile, and this works fine too.

func _on_enemy_area_3d_area_entered(area: Area3D) -> void:
	if area.is_in_group("Projectiles"):
		current_health -= area.damage_int

If this happens to work for you, then great, we found a workaround for now and at least you can continue with the course. If this also doesn’t work, then the best thing to do would be to make your project accessible to us so we can poke around in it. If you put it on google drive or something and provide a link here, I’ll experiment with it myself; otherwise we can get Marc or Darren in the loop, who will give you a way to upload the project directly to GDTV.

No stress; one way or another, it’s gonna get fixed =)

I am probably looking at the easiest problem that stands out and it may just be a typo or the way the forums have formatted this code paste but that should be “enemy_area” not ‘enemy_area’

1 Like

Yes, I noticed that too. Good eye either way, though I remember reading somewhere that Godot will support both single and double quotes properly as long as you don’t mix-and-match the quote pairs =)

When I noticed it, I decided to test this syntax in my project, and I can confirm it does actually work. I also ruled out the possibility of these marks being apostrophes (~ key) instead of quotes, since that would have changed the display formatting. And, because the problem print-statement happens before this line already, the root cause must be earlier in the code, or design-based.

@aheim, I do agree with Marc though and I would recommend making his proposed change: for simplicity, it’s always a good idea to stick to one quote style or the other until you explicitly need both (escape characters, etc.)

1 Like

Thanks for the help, everyone! I tried playing around with the quotation marks and am still encountering the same issue. I’ll try the alternative method of having the enemy check for projectiles. Also including a zipped version of my project for anyone that wants to take a look.

Project

Sometimes it really makes a big difference for us to be able to look into a project directly. You’ll have a laugh over this one I think - for some reason, your enemy’s CollisionShape was disabled in the inspector! That’s all it was =)

I was also able to determine that the reason you were still getting the occasional print statement output before, and not getting any groups associated with it, is because those messages were actually detecting collisions between [projectiles from different turrets] crossing over each other. Because the projectile’s _on_area_entered() doesn’t distinguish between enemy areas and projectile areas, the true problem ended up getting masked under these unintended messages.

If you’ve done Kaan’s 2D course, you’ll notice he usually adds an explicit check to see what the body (or area in this case) actually is, specifically to avoid logic like this executing when it shouldn’t. I think Bram does this as well, but not always (probably to keep syntax as beginner-friendly as possible). Anyway, what happened here is a good reason to consider adding that in.

Have fun with the course!

Thanks a ton BH! Of course it was something tiny haha. I must have disabled it by mistake. Just made the change and everything is working as expected!

1 Like

Nice catch!

1 Like

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

Privacy & Terms