How do i make ray-cast exclude all things but only collide with one particulate body?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By MCjelly

So I am trying to create a slash & hit effect for my game, whenever that the player tries to hit an enemy, the player would cast a ray, the effect would appear at the collision position. how ever, the player’s attack would hit multiple enemies. this is where the problem comes in, they ray would only hit and be blocked by the first enemy or worse, something else.

here is my code:

func _on_Attack_coli_body_entered(body: Node) -> void:
	var slash_effect = preload("res://crs/effects/attackanim/swordslide.tscn").instance()
	var spacestate = get_world_2d().direct_space_state
	var result = spacestate.intersect_ray(global_position,body.global_position,["exclude every one but 'body'"])
	
	print(result)
	
	get_parent().add_child(slash_effect)
	slash_effect.position = result.position
	slash_effect.rotation = (position - body.position).angle()+1.5

how can I make the raycast only cast on a particular body?

:bust_in_silhouette: Reply From: Simon

Hi, you can add a group on the body and use .is_in_group()

:bust_in_silhouette: Reply From: Macryc

intersect_ray also takes in collision_mask which you can use to determine which layer of objects the ray is to collide with:

intersect_ray(from: Vector3, to: Vector3, exclude: Array = [ ], collision_mask: int = 0x7FFFFFFF, collide_with_bodies: bool = true, collide_with_areas: bool = false)

:bust_in_silhouette: Reply From: MCjelly

Nvm, someone on Reddit helped me figured it out :slight_smile:

https://www.reddit.com/r/godot/comments/hzen7x/how_do_i_make_raycast_only_collide_with_one/

So what I did is I created an array for the body that needs to be excluded whenever the ray hits the wrong body, it adds that body to the array and re-raycast again until it hits the right body or hits nothing.

here’s my code:

var exclude_body = [self]
var hit_pos = Vector2.ZERO
var empty = true

while empty:
	var spacestate = get_world_2d().direct_space_state
	var result = spacestate.intersect_ray(global_position,body.global_position,exclude_body)
	if result.collider != body:
		exclude_body.insert(0,result.collider)
	else:
		if result.collider == body:
			hit_pos = result.position
			print(result)
			break
		elif result == null:
			break