Best way to apply damage when raycast hits a child node (Attackable parent)

Godot 4.4.1

Hi everyone, I’m working on a system where I want to apply damage to objects using raycasts. The problem is that my raycasts often hit a child node of an object (like a CollisionShape3D), but the actual damage logic (e.g., a Hurtable script or damage method) is located on the parent node.

For example, I have a scene like this:

scss
Copy
Edit
Enemy (Node3D) [in group “attackable”]
├── CollisionShape3D (gets hit by raycast)
├── MeshInstance3D
├── Hurtable (script handling health/damage)
When I do something like:

var hit = raycast.get_collider()

hit is usually the CollisionShape3D, but I want to call take_damage() on the parent Enemy node or its Hurtable script.

My questions:

What’s the best way to find the actual “damageable” node from the child that gets hit?

Is there a recommended pattern or utility function for this?

Should I rely on groups like “attackable” or is there a better approach using signals or components?

Thanks in advance!

Hi!

To my knowledge, there’s no absolute right way/pattern to do that. One thing you should know, however, is that when you have a CollisionShape below a CollisionObject node, you can attach a script to that CollisionObject and cast the raycast’s collider using that script’s class name.

For instance, say you have an Area with a script “Damageable”:
image
You could do that in your raycast script:

var raycast_result = space_state.intersect_ray(query)
if raycast_result:
	var collider = raycast_result["collider"]
	if collider is Damageable:
		collider.attack()

which is very convenient if you know your script is attached to the CollisionObject directly.
I don’t know the type of your Enemy node but if you have a CollisionShape3D as a child, I suppose it is a CollisionObject3D of some sort (Area3D, StaticBody3D, etc.), since CollisionShapes are meant to be children of such nodes.

:warning: I think that’s one way of doing it, but know that I’m no Godot expert so if I’m wrong, please correct my answer.

Let me know if that helps :slight_smile: