Godot Version
4.2.2
Question
Hello,
Slowly but surely I am getting very angry at Godot. I simply don´t get it.
I have an Area2D moving from side to side. I have another Area2D moving also from side to side. When both overlap, one of them should send a signal to the level node. But nothing happens. I´ve encountered this already multiple times.
I am using the are_entered signal. I have checked the physics layers. You can find them attached. They look right to me.
In the attached example I am sending the signal from the LaserAsteroid node.
Collision shapes are added.
Is it because the two areas can´t be moving at the same time?
Checked it. It´s not the reason.
This is completely blocking my progress at the moment. I hope somebody can help.


I also tried the following fix I found on reddit that said to unbind the arguments. Didn´t work:
Through lucky try and error it worked after a long time in other cases. But I don´t see a logic in it. Why is it working if I apply the signal to one of the Areas but not if I try it for the other Area2D. Shouldn´t it work independently of the Area2D?
The collision layer/mask look perfect. Have you tried running the game with “Visible Collision shapes” on?
Hi gertkeno,
Yes, that´s what I am doing. And I can see that the overlap.
Best regards!
Interesting, should work unless you’ve set the emitting Area2D “Monitoring” off. You’ve mentioned one node works, there anything different from that node to this one?
1 Like
Exactly. It should work. Monitoring is on.
I don´t know what to do anymore. Feels like a bug. I hope it´s just an error on my side.
Could you paste your script maybe? With the connected area2D functions
Do you mean as a file? or just the plain code as below. Sorry I am new to coding so I don´t know the best practices.
extends Node2D
@onready var tween_side_movement: Tween
@onready var tween_up_movement: Tween
@onready var current_marker_index = 1 #start always in the middle
##Create object for random numbers
@onready var rng = RandomNumberGenerator.new()
var markers =[]
var enemy_scene: PackedScene = preload("res://Scenes/Level/enemy.tscn")
var item_scene: PackedScene = preload("res://Scenes/Level/item.tscn")
var asteroid_scene: PackedScene = preload("res://Scenes/Level/asteroid.tscn")
var laser_asteroid : PackedScene = preload("res://Scenes/Level/laser_asteroid.tscn")
##Preload enemy textures to assign randomly later
@onready var enemyTextures = [
preload("res://Assets/Enemy_Skins/EnemySpaceships1000x1000red.png"),
preload("res://Assets/Enemy_Skins/EnemySpaceships1000x1000blue.png"),
preload("res://Assets/Enemy_Skins/EnemySpaceships1000x1000orange.png"),
preload("res://Assets/Enemy_Skins/EnemySpaceships1000x1000yellow.png")]
func _ready():
rng.randomize()
$Item.queue_free()
# Create markers for spawn of enemies & items
$LaneMarkers/MarkerLeftX.position = Vector2(Globals.cell_size*3 , Globals.cell_size*-0)
$LaneMarkers/MarkerCentralX.position = Vector2(Globals.cell_size*7 , Globals.cell_size*-0)
$LaneMarkers/MarkerRightX.position = Vector2(Globals.cell_size*11 , Globals.cell_size*-0)
markers = $LaneMarkers.get_children()
#Change beginning position if first enemy
$Enemy.position.x = markers.pick_random().position.x
$Enemy.position.y = 0
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
## Player movement based on swipe signal received from player
func _on_player_left_swipe():
if current_marker_index > 0:
current_marker_index -= 1
#print("Current marker Inder: ", current_marker_index)
update_position_side_movement()
func _on_player_right_swipe():
if current_marker_index < 2:
current_marker_index += 1
#print("Current marker Inder: ", current_marker_index)
update_position_side_movement()
func update_position_side_movement():
if tween_side_movement: tween_side_movement.kill() # Just in case the tween was already running
tween_side_movement = create_tween()
tween_side_movement.tween_property($Player, "position", Vector2(markers[current_marker_index].position.x, $Player.position.y), 0.15)
func _on_player_up_swipe():
update_position_up_movement()
func update_position_up_movement():
var laser_asteroid_inst = laser_asteroid.instantiate() as Area2D
add_child(laser_asteroid_inst)
laser_asteroid_inst.position = $Player.position +Vector2(0,-100)
func _on_player_area_entered(_area):
$Player.queue_free()
## create next enemie(s) once spawn area sends signal that enemy or item entered area.
func _on_spawn_area_area_entered(_area):
var asteroid_object_array : Array = [enemy_scene, enemy_scene, asteroid_scene]
if $TimerSpawn.time_left == 0.0:
$TimerSpawn.start()
var asteroid = false
var picked_marker_indices = [] # indices
var random_num = rng.randi_range(0, 1200) # Choose randomly if one or two or three markers to be chosen
if random_num <= 500:
random_num = 1
elif random_num >500:
random_num =2
#create probability for third enemy object (asteroid) that needs to be destroyed with swipe up
if random_num == 2:
var random_asteroid_chance = rng.randi_range(1, 10)
if random_asteroid_chance == 1:
random_num = 3
asteroid = true
else:
asteroid = false
while picked_marker_indices.size() < random_num:
var random_index = rng.randi_range(0, markers.size() - 1)
#add marker if not added yet | avoids doubled markers
if random_index not in picked_marker_indices:
picked_marker_indices.append(random_index)
# append the picked markers
var picked_markers = [] # needed to store the markers. Till now only indices picked
for index in picked_marker_indices:
picked_markers.append(markers[index])
# Use call_deferred to avoid modifying physics state while the engine is flushing queries
# Spawn enemies and asteroids. Two cases: one with 3 objects of which one must be an asteroid. Otherwise only enemies will be spawned
match asteroid:
true:
for marker in picked_markers:
var random_object = asteroid_object_array.pick_random()
var random_index = asteroid_object_array.find(random_object)
call_deferred("_spawn_enemy", asteroid_object_array[random_index], marker.position)
asteroid_object_array.remove_at(random_index)
false:
for marker in picked_markers:
call_deferred("_spawn_enemy", enemy_scene, marker.position)
# Define a separate function to handle enemy instantiation to avoid "can't change this state while flushing queries issue"
func _spawn_enemy(selected_spawn_object: PackedScene, spawn_position: Vector2):
var enemy = selected_spawn_object.instantiate() as Area2D
add_child(enemy)
# randomly select a texture
var randomEnemyTextureIndex = randi() % enemyTextures.size()
enemy.get_node("Sprite2D").texture = enemyTextures[randomEnemyTextureIndex]
enemy.position = spawn_position
func _on_laser_asteroid_area_entered(area):
print("laser has hit asteroid")
1 Like
Which of these functions do you want to trigger/are connected? I see last _on_laser_asteroid_area_entered
seems like the right function, but it’s totally empty
Oh sorry, there was a copy and paste error.
I meant:
func _on_laser_asteroid_area_entered(area):
print("laser has hit asteroid")
instead of:
func _on_laser_asteroid_area_entered(area):
pass
It doesn´t print anything though. At the moment I am not connecting any other function to it
The funny thing is, that even if I duplicate another existing Area2D that is sending out the signal correctly, the duplicate doesn´t work.
It´s really, really weird…
Are you connecting it with the unbind advanced option? I would recommend against that.
No, I did it only to see if it is affecting the bahavior but it didn´t change anything.
I am trying to set up a new project now and I will copy the scenes to the new project to see if there is some issue with the project set up.
Update: I set up the new project but that didn´t fix the issue. I still have no idea what´s going on. Even the easiest applications of Area2D signals do not work in this project but do in others.
I had a similar problem trying to detect collision between Area2Ds on a pickup and my player. The pickup had its collision_layer
set and it’s collision_mask
empty. The player had it the other way around
The problem was that I was listening for the area_entered
signal on the pickup, but it was actually only emitted on the player
So, make sure that the Area2D on which you connect is the one where you configure the collision_mask