godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
86.91k stars 19.47k forks source link

Area3D does not detect `body_entered` on StaticBody3D and RigidBody3D #74300

Open nox123 opened 1 year ago

nox123 commented 1 year ago

Bugsquad note: This issue has been confirmed several times already. No need to confirm it further.


Godot version

Godot Engine v4.0.stable.official.92bee43ad

System information

Vulkan API 1.2.231 - Forward Mobile - Using Vulkan Device #0: Apple - Apple M1 Max

Issue description

Area3d not detect (or send signal) body_entered when BODY is StaticBody3d or RigidBody3d it's detecting this object only when SB or RB starts in the area

CharacterBody3D is different case it is detected when it's entered, so it works properly

Steps to reproduce

-create Area3d with big colisionShape

Minimal reproduction project

Area3dBug.zip

AThousandShips commented 1 year ago

Related #66468

AThousandShips commented 1 year ago

Have you set the area to monitorable?

nox123 commented 1 year ago

Yes

TamerSoup625 commented 1 year ago

I'm also having this bug on v4.0.2.stable.official [7a0977ce2] with Windows 10 Home x64

I noticed that the area updates the overlapping bodies correctly if the area is moved or its parameters are updated, simirarly to #66468 where the area updates correctly with the change of collision layer/mask.

TamerSoup625 commented 1 year ago

For those of you who want an hack against this bug, constantly changing the collision layer if you're using an Area3D node seems to work:

func _physics_process(delta):
    # Considering "area" an Area3D, and layer 32 an unused layer
    area.set_collision_layer_value(32, not area.get_collision_layer_value(32))

However it doesn't work if you're using servers for some reason, in which case it seems like only changing the monitorable property works:

func _called_every_physics_frame():
    # Considering "area" a RID pointing to a PhysicsServer3D area
    # Changing twice to ensure the monitorable property stays constant
    # If you want the area to be not monitorable, just swap places of the two lines of code
    PhysicsServer3D.area_set_monitorable(area, false)
    PhysicsServer3D.area_set_monitorable(area, true)
JTimNolan commented 1 year ago

Also having this bug. Windows 10 Pro x64 Vulkan API 1.2.168 - Forward+ - GTX 780

DennisManaa commented 1 year ago

I also can confirm this or at least a similar issue on Ubuntu 22.04 x64 RTX 4090 Vulkan API 1.3.204 Forward+

@TamerSoup625's solution worked for me. I was using $Area3D.get_overlapping_bodies() for querying different non-moving physics-bodies. In my project it seems like the overlapping bodies aren't updated correctly during the physics step, when disabling and re-enabling a CollisionShape of a StaticBody3D which is inside of the Area3D (using the disabled-flag of the StaticBody3D).

Disabling seems to work correctly, but re-enabling a StaticBody3D inside of the Area3D seems to not be registered correctly by the Area3D.

Edit: The Area3D also was not moving. So none of the objects in my scene was moving.

ee0pdt commented 1 year ago

Same issue with RigidBody3D entering an Area3D on Mac in Godot 4.1

coldi commented 9 months ago

I also ran into this issue with Godot .NET 4.1.2. GetOverlappingBodies() doesn't work (calling it in _PhysicsProcess) and signals don't trigger either for StaticBody3Ds. I've double checked all collision layers and masks.

I can confirm the Area3D works in the very first _PhysicsProcess step, but it does not report anything else during lifetime / doesn't detect any changes.

matthewhilton commented 9 months ago

Re the workaround by setting monitorable / collision mask - https://github.com/godotengine/godot/issues/74300#issuecomment-1519064875

Just discovered that neither of these work with Godot-jolt physics, and it has the same issue

nulflux commented 8 months ago

I'm piping in to add that this has been present since 4.0 at least. I don't believe it is limited to a certain type of node since this happened to me with a skeletal system inside a Node2D. I for whatever reason tried to change the root node to AnimationPlayer and poof the rig was gone. I learned not to change note types it's better to just create a brand new one. It is definitely a bug. This has been reported before and I think I commented on that one too.

My0Cents commented 8 months ago

Using Godot 4.2 Beta 6 and I'm having the same issue.

ChildLearningClub commented 7 months ago

This made its way into 4.2 Stable Godot Physics

https://github.com/godotengine/godot/assets/25701774/d3746f41-1820-4c6d-97c0-ef753228e712

Same Scene With Jolt Physics

https://github.com/godotengine/godot/assets/25701774/86e9d770-7caf-4ea4-be1d-ca4b2a946f5b

MRP

bdasuncion commented 6 months ago

I have a similar situation in that I'm using a CharacterBody3d. During testing, when my CharacterBody3d isn't moving, the signal body_entered isn't triggered. When I put movement, then its triggered. Or similarly if it starts with the CharacterBody3d inside the Aread3d, then it is triggered as well

richardathome commented 6 months ago

I'm on 4.2.1 [b08f793f5] Windows 11 Home and experiencing this issue.

None of the fixes above worked for me. (detecting a RigidBody3D entering an static Area3D).

The only way I could get it to work is to jiggle the area 3d a tiny amount each _physics_process:

@onready var pos = global_position

func _physics_process(delta: float) -> void: global_position = pos + Utils.random_vector3() * .001

golddotasksquestions commented 6 months ago

I just tested this with nox123 MRP in Godot 4.2.1 stable and 4.3 dev2 on Windows and can confirm the StaticBody3D issue, however RigidBody3D (and CharacterBody3D) seems to work as expected. I also tested different collision shape (BoxShape3D), but that did not any a difference.

bikemurt commented 5 months ago

I am also getting this bug in 4.2 but only when I preload a packed scene and then programmatically instantiate it at runtime. Doesn't matter if it is instantiated in _ready or _process, the area_entered/exited signals do not fire.

If I manually bring in an instance of that packed scene into my scene, the area3D signals work fine.

This may strongly hint that something is not getting initialized with the layers/masks/etc when being done programmatically.

Edit: but I should note that @TamerSoup625's suggestion above does not appear to fix it in this case (could be due to Jolt, however)... could be multiple bugs

Edit 2: figured out my problem (not an engine bug), but leaving this comment here because it may help someone else. My Area3D needed to be inside my RigidBody3D, because physics was acting on it and moving the object around. If the area3D is outside the RigidBody3D, then it gets "left behind" as the object moves.

nicolasgustafsson commented 5 months ago

Got this issue with CharacterBody3D, after disabling the process mode(with Disable mode set to Remove) then reenabling it, and only rarely. Switching to Jolt-physics did not resolve it for me.

Using 4.2.1 stable

Following this did make it work for me, with Jolt too:

#74300 (comment)

ScriptSlinger commented 5 months ago

Got this issue with CharacterBody3D, after disabling the process mode(with Disable mode set to Remove) then reenabling it, and only rarely. Switching to Jolt-physics did not resolve it for me.

Using 4.2.1 stable

Following this did make it work for me, with Jolt too:

#74300 (comment)

You have to enable an option in Jolt settings. Took me 2 hours to find out.

Kantrul commented 4 months ago

Got this issue with CharacterBody3D, after disabling the process mode(with Disable mode set to Remove) then reenabling it, and only rarely. Switching to Jolt-physics did not resolve it for me. Using 4.2.1 stable Following this did make it work for me, with Jolt too:

#74300 (comment)

You have to enable an option in Jolt settings. Took me 2 hours to find out.

For anyone using Jolt, the setting is in the project settings imagen

Pikari0 commented 3 months ago

Having this issue too, Godot 4.2.1 stable on Linux, not using Jolt. If I use "change type" on an undetected StaticBody to change it to CharacterBody, suddently it's detected, and changing it back, it's undetected.

rcjoel2019 commented 3 months ago

If you come by this and are spawning an Area3D to verify if it has a body inside it, the Area3D only sees what enter or exits of it, if you want to detect all bodies in a area (ex: during an explosion, searching all damageable bodies on that frame), you can check directly on the Physics server using:

var space := get_world_3d().direct_space_state
var search = PhysicsShapeQueryParameters3D.new()
search.transform = global_transform
var shape = SphereShape3D.new()
shape.radius = 4
search.shape = shape
var bodies = space.intersect_shape(search)

Check the docs on PhysicsDirectSpaceState3D for more details.

emersonbottero commented 2 months ago

For me it does not work only between instance of the same scene. Tower can detect body_entered with wall but can't detect body_entered with another Tower.

PickleOnAString commented 1 month ago

still happening in 4.3 beta 1. i'm happy to try to fix this but don't know where to start