godotengine / godot

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

CharacterBody3D move_and_slide() freezes the game when colliding with Concave Collision Polygons or ConvexHulls #70453

Open alfredbaudisch opened 1 year ago

alfredbaudisch commented 1 year ago

Godot version

4.0-beta9 and 4.0-master-branch

System information

Windows 10, Ryzen 9 5900X, GTX 3080Ti

Issue description

When moving a CharacterBody3D using move_and_slide() and colliding against a Concave Collision Polygons or ConvexHulls with >100 vertices, processing freezes from many ms to sometimes seconds:

https://user-images.githubusercontent.com/248383/209200310-13cd77c4-fa4b-4530-8c4f-7626791e3dd1.mp4

Similar issues

This may be a duplicate of other similar issues like https://github.com/godotengine/godot/issues/50300, but my case was requested by @reduz via Twitter.

Steps to reproduce

Minimal reproduction project

GodotFreezingCharacter3D.zip

This test project has 4 character controller implementations (2x 1st Person and 2x 3rd Person ones), to show that it happens regardless of the controller complexity or simplicity:

imagen

To test, simply move forward (WASD + mouse) and collide against the barrels, then move around colliding with the barrels and also collide with the walls, to see the difference (like my example video above).

rburing commented 1 year ago

As far as I can tell the problem with convex collision is different from the problem with trimesh collision.

Collision with the trimesh collision shapes causes lag spikes (FPS drop) because there are 1444 triangles in each barrel.

To change the collision shapes to convex: in the advanced importer for the FBX file, change Physics Shape Type to Simple Convex, press Reimport, and restart the editor (for some reason reimport seems bugged currently).

Collision with the convex collision shapes does not cause lag spikes (FPS remains stable) but you get stuck/caught on them instead of sliding along them, almost certainly because of the almost coplanar adjacent faces, see https://github.com/godotengine/godot/issues/65596#issuecomment-1242948809.

reduz commented 1 year ago

I did some research here and it appears that the problem here regarding what kills performance is that the way we do the sweep test here is pretty inefficient, this should be redone to use a proper GJK based sweep test.

Saul2022 commented 1 year ago

Seems like it persists on the beta 14.

jitspoe commented 1 year ago

I've noticed that, even with pretty simple geometry, the framerate completely tanks on development builds when using move_and_slide(), especially when a character moves into a corner where, I assume, multiple contacts are generated. move_and_collide() isn't quite as bad, but still results in sub-60 FPS. Hoping this pending change will improve it!

alfredbaudisch commented 1 year ago

the framerate completely tanks on development builds when using move_and_slide(), especially when a character moves into a corner where,

I know the issue is still open, which is a confirmation that the issue is still present. But just to make sure, I re-tested, and I want to confirm that this is still the case with 4.0-stable. Also, my MRP from the issue still performs as badly as originally (i.e. the issue still persists as reported).

jitspoe commented 1 year ago

I just had another issue that I think is related. I recently set up my spawners so they could be placed directly on the ground and I would read in the height of the capsule of the player and enemies to offset them and place them exactly on the ground. After I did that, I the game ran at like 10-15 FPS for a few seconds then acted normally. On subsequent runs, it didn't do that, but every once in a while it has that behavior. Framerate is completely unplayable for a few seconds then it settles down.

Unfortunately, it reproduces rarely, and this is on a larger project, so I can't come up with a consistent minimal repro case. Also, the profiler doesn't indicate where the performance hit comes from. It was all under "Process time", not on any of the script functions or physics. Perhaps something needs to be added to the proper profiler category to help track this down for certain.

TechnoLukas commented 11 months ago

I do have similar issue on Godot 4.2.1. I don't use move_and_slide, I use move_toward and lean in the direction. Also added particles to visually see the "lag"

STEPS:

This is my demo project: https://github.com/TechnoLukas/Godot4-Basic3dStarter/tree/simplified

alfredbaudisch commented 11 months ago

@TechnoLukas while not a solution to Godot's physics, I recommend that you use Godot Jolt. I have long abandoned the usage of Godot Physics in favor of Jolt and these issues are not present.

TechnoLukas commented 11 months ago

@alfredbaudisch Thank you! Yes, Godot Jolt solved this issue, and made physics more smooth. 👍

sinaSPOGames commented 9 months ago

this is not just character 3d or something like that same goes for Rigid bodies as well with same collision type

maridany1999 commented 5 months ago

I'm using Version 4.3.dev6.mono, this issues still exists. I'm using a CapsuleShape3D as the collision shape for the player and MoveAndSlide to move the player. Additionally, the collision the player is colliding agaisnt is round shape but with only 50 vertices.

Also, I've come to notice that everytime there's low fps spikes, colliding agaisnt specific collisions and at certain angles, the value of active objects and islands lower to 1, which is when the fps decrease a lot.

image

The image below also shows the profiler, more specific the Physics 3D section. When the FPS drop drastically, at the exact moment that the active objects also lowers from 2 to 1, it also creates an loop of items repeating itself: image