Godot Version
Godot Engine v4.4.dev.custom_build.cb411fa96
Question
I’m trying to track the overlap status between two different areas. Generally it works fine, so everything seems to be setup okish, like
Body1 has a hurt area on layer 7 and masks layer 4 with monitorable
set to false
Body2 has a hit area on layer 4 and masks layer 7 with monitoring
set to true
Placing them apart from each other so that the areas don’t overlap,
then setting Body1 monitorable
to true
and finally moving them towards each other until the areas overlap triggers area_entered
on Body2.
In special cases i want to set Body1 monitorable
to true while their areas are already overlapping.
This won’t trigger area_entered
on Body2.
They first have so be moved apart so that the areas stop overlapping and then moved towards each other so that the areas begin to overlap again to finally trigger area_entered
on Body2.
Is this expected behavior?
To work around this state i guess i could just set body1 monitorable
to true from the beginning and suppress its action with a flag but it feels hackish.
What’s the idiomatic way to initialize the overlapping status in this special situation?
Here’s a minimal reproducible example:
var e
var t
var s : int = 0
func nxt():
s += 1
match s:
1:
e = spawn_enemy(enemy1, Vector2(500,500))
t = spawn_tower(tower1, Vector2(600,500))
t.hurt_area.monitorable = false
2:
t.global_position = Vector2(550,500)
3:
t.hurt_area.monitorable = true
# doesn't force the event to signal: t.global_position = t.global_position
# doesn't force the event to signal: t.set_deferred("global_position", t.global_position)
# this forces the event to signal
#var op = t.global_position
#t.global_position = Vector2(600,500)
#get_tree().create_timer(.0).connect("timeout", func (): t.global_position = op, ConnectFlags.CONNECT_ONE_SHOT)
func _input(event):
if event is InputEventMouseButton and event.pressed:
match event.button_index:
MOUSE_BUTTON_LEFT:
nxt()
e is Body2 and
t is Body1
nxt()
will take one step through a state machine on each left mouse click.
I’d expect the area_entered
event on Body2 to signal on step 3 but it doesn’t.
Setting the position to itself didn’t work in my tests, also not deferred.
What helped was to first move it out of the area and set a timer to move it to its previous position again.
This feels pretty ugly.
Is there a less complex and more idiomatic way which doesn’t involve timers?
I also posted the question on reddit.
EDIT:
I edited the code based on the suggestions (from events to Area2D.get_overlapping_areas()
) and pushed it to github.