Godot Version
4.4
Hi, I have an issue that has me stumped. I have an area2D that was working perfectly, but I needed to increase its size. After doing this, it has stopped interacting with rigidbodies. I’m using body_entered()
and body_exited()
, I’ve checked and monitoring is still toggled on. I tested it once before the change and it was working, and after increasing its size, it stopped working. I have since tried putting it back to its original size, and it remains broken.
Other recent changes:
- I placed the whole scene inside a larger area2D that acts as a killbox.
- I added a script to the root node of my rigidbody scenes that deletes them if triggered.
Neither of these things should have an effect on this problematic Area2D, I also removed the second Area2D from the scene to check, and the broken one remained broken.
Here is its script:
extends Area2D
func _on_body_entered(body: Node2D) -> void:
body.set_collision_layer_value(2, false)
body.set_collision_mask_value(2, false)
body.set_collision_layer_value(3, false)
body.set_collision_mask_value(3, false)
print_debug("still here")
func _on_body_exited(body: Node2D) -> void:
body.set_collision_layer_value(2, true)
body.set_collision_mask_value(2, true)
body.set_collision_layer_value(3, true)
body.set_collision_mask_value(3, true)
print_debug("gone")
and here are its signals, it’s pointing at itself:
The intent is to remove collision from layers 2 and 3 of objects entering it, and give it back when they leave. The print_debug()
s are to help me see if it detects anything. The collision is no longer being removed or re-added, and all the print_debug()
s stopped printing.
Reverting my changes has not fixed the issue.
I’ve not had an issue like this in Godot before. I had a similar problem in GameMaker that turned out to be a bug in GameMaker’s compiler, and I really hope it’s not the same story here.
I don’t think you need to do this? My understanding is that body_entered
triggers once when the body enters the area, and doesn’t trigger again unless it leaves and then re-enters.
Are you sure the layer values and mask values are initially set?
1 Like
I don’t think you need to do this? My understanding is that body_entered triggers once when the body enters the area, and doesn’t trigger again unless it leaves and then re-enters.
I’m not sure what it is I don’t need to do, I think you need to be more specific, sorry. Also, objects are entering and leaving the area all the time, so I need to re-enable the collision when they leave the area, and disable it again if they enter again.
Are you sure the layer values and mask values are initially set?
Just checked; the layer 2 rigidbody is set to layer 2 mask 2, and the layer 3 rigidbody is set the same way for layer and mask 3. The Area2D is set to interact with layer and mask 1, 2, and 3. And again, it’s monitoring and monitorable.
I’m making one of those bouncing ball videos for YouTube to learn physics and shaders better. This singular Area2D is no longer detecting anything at all now. I just gave it an area_entered
signal to detect other area2Ds, and it won’t detect those either.
Oh, and I think I should note the script is flawed. Ideally it wouldn’t be giving the layer 2 rigidbody collision with layer 3, but before I could start fixing that, I got distracted by the Area2D ceasing to function between tests.
What I mean by “I don’t think you need to do this” is:
If you have a body enter an area, I’m fairly certain it will generate the body_entered
signal once. Not once per frame as long as it’s in there, once, the first frame it enters. It will then emit body_exited
once, on the frame it leaves.
So, you don’t need to turn off collision when you get the body_entered
signal, you won’t get that signal again unless it leaves and comes back.
In fact, by turning it off, you’re turning off the thing that would have generated the body_exited
signal, because collision is now disabled, so nothing’s going to call body_exited
and turn collision back on. Collision would have to still be on to generate the signal, so you’ve disabled the thing that would turn collision back on.
So, as I see it, this can’t work, and even if it did work it would be doing something redundant.
1 Like
All of what you’ve said is correct except this:
In fact, by turning it off, you’re turning off the thing that would have generated the body_exited signal, because collision is now disabled, so nothing’s going to call body_exited and turn collision back on. Collision would have to still be on to generate the signal, so you’ve disabled the thing that would turn collision back on.
I leave collision layer 1 intact. I’m using that to detect collisions with areas, layers 2 and 3 detect collision with the external boundary. When within the Area2D, the rigidbodies are supposed to no longer collide with the external boundary, so they can escape it.
The white colliders are usually invisible, I made them visible to help show what I’m doing. What’s supposed to happen is the collision is disabled between the circles and the boundary colliders only if the circles could reasonably leave the “gap”, which is where I’ve placed the Area2D. I widened the gap, so I widened the area; now the area isn’t detecting collisions with physics objects or other areas. It needs to do that.
It’s hooked up to a node that’s scripted to align the Area2D’s CollisionPolygon2D
with the gap and rotate it accordingly. (this part appears to be working, and even if it wasn’t, the rigidbodies bounce around enough they should intersect with the Area2D eventually anyway, which would show me it’s working.)
Also, I placed the circles outside their boundary to test the killbox. That Area2D is detecting them just fine and only detects collision layer 1. The broken one is also set to detect collision layer 1, as well as other layers.
Also, whether or not what I’m doing is redundant doesn’t seem relevant to my issue. The problem I’m having is an Area2D has mysteriously stopped detecting any and all collisions on all layers. If this happened again in a situation you wouldn’t find redundant, how would I fix it?
Problem: altering the size of a CollisionPolygon2D sometimes breaks its collision.
Solution: Don’t copy/paste the whole node, that copies the problem too. Make an identical one, copy the values from the old node to the new node, then delete the old one.
I had an idea. I copy/pasted the Area2D and its children: copy was also broken. Then I recreated the Area2D exactly: same collision layers, same CollisionPolygon2D with identical dimensions, same signals, same script. It works. I don’t know why it works, but it works.
I now want to replicate the problem so I can figure out how to prevent it in the future and provide a good solution for others with the same issue, but I can’t. Altering the size of the collision polygon of this new identical Area2D does not break it.
The more I look at this, the more I think my hunch that I ran into an engine bug is right, but I can’t reproduce the issue so I don’t know if there’s value in reporting it.
@hexgrid thank you for your help, I’m sorry if I came across as hostile or ungrateful, I was very frustrated by this issue, and very tired. I made this topic after a couple hours of debugging, and now, two hours later, I fix it by doing basically nothing. It’s 4am now, I’m going to sleep.
1 Like