godotengine / godot

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

Shapecast reporting incorrect normals at the corners of tiles #86223

Open iv-island opened 10 months ago

iv-island commented 10 months ago

Tested versions

Reproducible in 4.1.1 and 4.2.1

System information

Godot v4.2.1.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3070 (NVIDIA; 31.0.15.4584) - AMD Ryzen 5 5600X 6-Core Processor (12 Threads)

Issue description

Using the physics layer of a tileset I created a Tile with a 45 degree slope and had the player move down and up the slope. The shapecast is pointed directly down and reports the normal of the slope. When moving on the slope the shapecast will sometimes report a vector with cardinal direction normals e.g. (0,-1) (1,0) (0, 1) seemingly randomly. The image shows the output printing the players report floor normal, the shapecast normal, and a raycast normal that is casting from the center of the player. The raycast never reports (0,-1). image

Steps to reproduce

To reproduce this issue I created a brand new project and imported a tileset, and added some physics layer collision to tiles to create a 45 degree slope. Then I had the player move down the slope and changed the engine time_scale so that it would move less between each normal report. I moved the player to the right and applied gravity and it would report (0,-1) sometimes, most likely due to delta resulting in less precise movement. I also tested a small debug check that would move the player from one point on the slope down the slope at 0.1 increments and then report the shapecast and position when the shapecast is (0,-1) each of these positions coincided with the corners of tiles.

Minimal reproduction project (MRP)

Test.zip

iv-island commented 10 months ago

After thinking a bit more on it, from some other things that I've read regarding ShapeCasts it seems like it is caused by the shape. Testing it out with the rectangle ShapeCast that I had initially it results in the (0,-1) normals at the edges of tiles but with a circle ShapeCast it works fine. Alternatively there are some dimensions of the rectangle that it does report the correct normal but others do not.

AThousandShips commented 10 months ago

I'd say this is to be expected, the normal at a corner like this is undefined, especially when considering precision never being guaranteed to be exactly on it

Calinou commented 10 months ago

Consider using barycentric coordinates for gravity changes, which were implemented in 3D by https://github.com/godotengine/godot/pull/71233 but don't have a 2D counterpart yet.