I have a setup where if the gun is active, update_current_target()
is called in physics process.
What it should do is first get all bodies in RangeDetector
which is an Area2D and then filter it to get only those in the specified group.
Then it uses AimCheck
, which is a Raycast2D, to check if there is a clear line between the gun and the targets.
Then it gets the nearest target and sets it as the gun's primary target.
I noticed that it doesn't work as expected with some test objects i set to pass by.

The east target touches first and the raycast targets it immediately. But get_collider()
first returns [Object:null], then correctly sets it as the target in a split second then suddenly ignores it as though it's no longer a valid target.
The north target is tracked correctly from when it enters to when it exits. As it nears the bottom edge the south target becomes the nearest but it's ignored even after the north target leaves the area. Then it tracks the south target for less than a second and then stops.
It ignores the west target as expected since a static body is blocking it.
var current_target: Node
func update_current_target():
var target_node: Node
var possible_nodes: = []
var clear_nodes: = []
for item in RangeDetector.get_overlapping_bodies():
if item.is_in_group(target_group):
possible_nodes.append(item)
for item in possible_nodes:
if has_clear_shot(item):
clear_nodes.append(item)
if clear_nodes.size() > 0:
target_node = clear_nodes[0]
for body in clear_nodes:
if (body.global_position - self.global_position).length() < (target_node.global_position - self.global_position).length():
target_node = body
else:
target_node = null
current_target = target_node
func has_clear_shot(target: Node):
AimCheck.set_cast_to(target.global_position - self.global_position)
return AimCheck.get_collider() == target
I spent a lot of time and i still don't know how to fix it. My best guess is that get_collider()
returns the wrong node even after setting its cast vector but that doesn't make sense.