Ok, finally came up with a solution:
I started searching how to do some raycasting programmatically and found the Physics2DDirectSpaceState
which does not only shoots raycasts but have the intersect_point()
method, exactly what I needed.
So, in the _input()
of my stage I used:
if event.type == InputEvent.SCREEN_TOUCH and event.is_pressed()
hit_position = event.pos
hit_position
is a stage variable that holds the last click / tap position.
Now we use the PhysicsSpace
to check if any of the targets got hit on the _fixed_process()
. It' s a physics action, so we use the physics process:
if hit_position != null:
hit_targets = get_world_2d().get_direct_space_state().intersect_point(hit_position, 1)
if not hit_targets.empty():
hit_targets[0].collider._get_hit()
else:
_miss()
hit_position = null
This code did not worked at first, while being the same used in the docs. After having a long and hard time figuring it out, let me make this clear:
Physics2DDirectSpaceState
intersect functions do not work with
Area2D
+ ColliderShape2D
, they need a PhysicBody2D
+ ColliderShape2D
to compute
intersects. So, changing the target node from Area2D
to
StaticBody2D
was the final trick to make it work.
As a bonus anwser for my last question, in the intersect_point(hit_position, 1)
the 1
represents how many bodies do you want to return from the intersect, the default is 32
. I wanted to eliminate only one target per click / tap, so I used 1
. You can use this to handle multiple collisions from overlapping nodes, and use a for loop to iterate and process them as you wish.
Thanks for the anwsers @rustyStriker and @mollusca!