• 2D
  • Use Intersect Ray to detect only a single Body [ANSWERED]

Hello again. Today's riddle. I am using a RayCast 2d to make a monster chase a player and also using the player's input to parse which direction the monster should go (my game is heavily inspired by Clock Tower, and movement is in one axis, right to left or vice-versa.) Thanks to some feedback, I am moving to the intersect_ray method instead. I only need to change which way it faces when necessary and not have it run away as the player moves towards it of course.

I have tried set_cast_to() and force_raycast_update() with RayCast2D and the docs didn't have much guidance. Advice?

Could you use two Raycast2Ds, and enable/disable them when the player turns? If not, you could probably use intersect_ray to make the checks.

@duane said: Could you use two Raycast2Ds, and enable/disable them when the player turns? If not, you could probably use intersect_ray to make the checks.

I did see the intersect_ray but I am struggling to grasp the implementation from the docs. Here is where I attempt to use it. My movement functions are decoupled safely away. Seems the queries just aren't doing anything (that I need them to.)

the monsDir variable is a simple Vector2(0,0) as a reference for the monster's movement that is calculated to speed. (Basic 2d movement stuff you all know, it's not what's broken. Yay for decoupling!)

AIMING FOR: If player is on right, monster walks right. If on left, vice versa. I also have some player movement tied to monster movement as its a nice shortcut to make it chase. Only problem is it also makes the monster go the opposite way if you press it. (The game only has left/right movement) There are only 2 bodies. All other objects are areas. So I want to implement the collide_with_bodies check but I keep getting a debugger error: My debug message below is not printing so obviously that's the error. They ARE in the same collision layer, I checked. They are also both instancing from the same object so I don't think (hope) inheritance is messing up anything.

func line_of_sight():
	var vision = get_world_2d().direct_space_state
	var field = get_viewport().size
	var spotting_right = vision.intersect_ray(self.global_position, Vector2(field.x,0), [self])
	var spotting_left = vision.intersect_ray(self.global_position, Vector2.ZERO, [self])
	
	if "collide_with_bodies" in spotting_right:
		print("Spotted!")
		walk_right()
	if "collide_with_bodies" in spotting_left:
		print("Spotted!")
		walk_left()

Thank you @duane once again.

I wasn't getting dictionaries on physicsQuery and found that, lo and behold, I DID have the monster in the wrong collision mask and my code was way off. However, i added some abstraction layers and sharpened it and my problem is solved. It also gave me another invisible stat to tweak with my monster, how fast it turns. (An exported variable in the header, called turnGap, defaults at 1 second)

func line_of_sight():
	### get world space, port size, exclude others objects, x and y limits
	var vision = get_world_2d().direct_space_state
	var field = get_viewport().size
	var exclude = [self, Area2D, StaticBody2D, RigidBody2D]
	var head = self.global_position.y
	var feet = self.global_position.x
	
	### check for ray intersect in both directions
	### first argument origin, second arg terminus, third is array for ignore
	var spotting_right = vision.intersect_ray(Vector2(feet,head), Vector2(field.x,head), exclude)
	var spotting_left = vision.intersect_ray(Vector2(feet,head), Vector2(0,head), exclude)
	
	### add a gap to turning and change movement if ray intersects
	yield(get_tree().create_timer(turnGap),"timeout")
	if spotting_right:
		print("Spotted!")
		walk_right()
	if spotting_left:
		print("Spotted!")
		walk_left()