Raycast2d collision not working as intented

Godot Version

4.4.1

Question

spell_raycast_bounce collision is indicated by red damage text
Issue is that spell_raycast_bounce collides with the spell_raycast collision point instead of colliding with the test enemy (blue silhouette)

Hit from inside is disabled
I don’t know how or why this is happening. please ask if you need more info

func ray_bounce(_delta : float) -> void:
	global_position = parent.global_position + parent.spell_direction.normalized() * 30
	direction = parent.spell_direction.normalized().rotated(deg_to_rad(angle_offset))

	parent.mana -= spell["mana"]
	spell_raycast.target_position = direction * spell["size"]

	if spell_raycast.is_colliding(): 
		if spell_raycast.get_collider() is StaticBody2D: #collision with enviroment
			var collision_normal = spell_raycast.get_collision_normal()
			var collision_pos = spell_raycast.get_collision_point()
			var reflected_dir = spell_raycast.target_position.bounce(collision_normal).normalized()
			spell_raycast_bounce.position = to_local(collision_pos)
			spell_raycast_bounce.target_position = reflected_dir * (spell["size"] - to_local(collision_pos).length())

		elif spell_raycast.get_collider().is_in_group(hostile): #collision with enemy 
			spell_raycast_bounce.position = spell_raycast.target_position
			spell_raycast_bounce.target_position = Vector2.ZERO
			_on_spell_area_body_entered(spell_raycast.get_collider())

		if spell_raycast_bounce.is_colliding(): # bounced ray collision with enemy 
			print(spell_raycast_bounce.get_collider())
			if spell_raycast_bounce.get_collider().is_in_group(hostile):
				_on_spell_area_body_entered(spell_raycast_bounce.get_collider())

	else: # no collision
		spell_raycast_bounce.position = spell_raycast.target_position
		spell_raycast_bounce.target_position = Vector2.ZERO

screenshot for readability

Line 133. Are you sure there is no confusion between global_position and local_position on that variable?

1 Like

Yes, as far as I’m aware the code block (line 132 - line 135) is handling collision with an enemy without a bounce so spell_raycast_bounce should not be relevant.
I tried this spell_raycast_bounce.global_position = collision_pos at line 129 but with no new result

Don’t test bounce ray on the same frame you’ve set it. The collision will happen on the next physics tick so what you’re getting is likely from the previous physics tick. Update both rays every frame and always only use bounce ray for determining the final result. If there is no bouncing, make the rays coincide. Let the first ray only register walls.

1 Like

Update both rays every frame and always only use bounce ray for determining the final result

So i should split my ray function into two pieces, one that sets the rays and another that checks collisions? Or do you mean to use force update after setting it

Let the first ray only register walls.

The bounce is an additional attribute (basic spell dosent have bounce). the first ray should be able to hit enemies aswell

Start by splitting it, yes. When you make this working you can experiment with forcing it if needed.

Let rays have fixed responsibilities to avoid confusion. The ray that hits the enemies should always be the same ray. When the bounce is attained the ray added should be the “first” ray, and let it only collide with walls.

2 Likes

couldnt really get it to work but fixed it by changing line 129 to spell_raycast_bounce.global_position = collision_pos - collision_pos.normalized() # - collision pos norm to prevent hitting from inside

Weird that hit from inside didn’t work
I feel i understand raycasts a bit more. Thanks for the help! :slight_smile: