godotengine / godot

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

Tilemap colliders have inconsisent behavior with move_and_slide() Max Angle (see pictures) #92621

Open robcbryant opened 3 months ago

robcbryant commented 3 months ago

Tested versions

Reproducible in: v4.3.dev4.official [df78c0636]

System information

Godot v4.3.dev4 - Windows 10.0.19041 - Vulkan (Mobile) - dedicated AMD Radeon RX 5600 XT (Advanced Micro Devices, Inc.; 31.0.21029.6002) - AMD Ryzen 7 3700X 8-Core Processor (16 Threads)

Issue description

Max Angle as a property for move_and_slide() doesn't work in a very specific condition where a slope doesn't register (and is treated as a wall) unless there is a contiguous collider setup. It's hard to describe in words, but the images should do it justice. Basically--if a slope is attached to a flat "plane", but there is an empty square connecting them, the Max Angle doesn't work. If there is an arbitrary square collider that connects the slope to an existing flat plane it works fine. It's an easy fix in-engine to take into account, but I suspect people will have issues with this in 2D games

In this image the empty square tile of collision is the issue--Max Angle does not work properly--and this slope will be treated as a wall. bug_report A

In this image, with an added arbitrary square box collider to this tile, max angle DOES work as expected. Without this tile to make the entire tilemap collider a contiguous polygon, max angle will not work and the incline will be treated as a wall. In tilemaps--all tiles should form a contiguous polygon collider without gaps. This should be made well known in documentation or fixed so that it doesn't matter if the tilemap colliders are contiguous or not. bug_report B

Steps to reproduce

As per above--just make a tile map with various slope colliders that don't create a contiguous polygon at the vertices

Minimal reproduction project (MRP)

n/a

AThousandShips commented 3 months ago

This isn't specific to tiles so should be documented in the physics tutorials, but I think it shouldn't be surprising that a gap means it's not considered a floor, "mind the gap" as it were

robcbryant commented 3 months ago

This isn't specific to tiles so should be documented in the physics tutorials, but I think it shouldn't be surprising that a gap means it's not considered a floor, "mind the gap" as it were

I think that's fair. I think the confusion for me stemmed from the tilemap colliders seemingly sharing a pixel vertex at those joins, but when actually seeing them in engine, there's a small imperceptible gap which causes the behavior unless there's another bridging collider to connect them together.

AThousandShips commented 3 months ago

So the screenshot above is exaggerated for effect? That gap is hardly imperceptible

robcbryant commented 3 months ago

So the screenshot above is exaggerated for effect? That gap is hardly imperceptible

Taken directly from the game running with debug colliders turned on. Because of the debug colliders not necessarily being pixel perfect, the noticeable gap changes based on camera position. In the shot below--it's not noticeable. bug_report C

I'm not sure if it's a bug per se--and easy enough for me to solve by ensuring there are enough buffer collision boxes to account for this, but figured I'd report it since I was reporting on something else with the dev/beta builds anyway.

I'm working off the assumption that if I manually placed three 2D colliders outside a tilemap system and had them positioned in the same manner, the issue wouldn't persist, e.g.,: bug_report D

If it's a godot/gamedev standard to assume the example on the right is the preferred way to handle collision work, then that's fine, I was just ignorant of the fact. Also thanks for responding! I know everyone's busy trying to get 4.3 out!

Side note: the issue also doesn't occur if already on a slope--it only seems to occur when transitioning from a flat surface to a slope or a 45 degree or higher change in slope. That's why I pointed out the non-issue in the image above.

AThousandShips commented 3 months ago

I think some kind of note could be added to the 2D physics tutorials about gaps and edges, but I'm not sure how it should be worded to be useful

robcbryant commented 3 months ago

I think some kind of note could be added to the 2D physics tutorials about gaps and edges, but I'm not sure how it should be worded to be useful

Awesome! I agree it's difficult to word/describe, which is why I finally had to draw that graphic lol. Maybe something similar that just says "For smooth slope movement, ensure your colliders have overlap to account for move_and_slide()'s processing, see image:"

Thanks again! Like I said, this no longer affects me now that I figured it out, but thought it was useful to share. Should I close out this bug report?

AThousandShips commented 3 months ago

Let's keep it open to see how to proceed with further documentation! And you're very welcome thanks for a nice chat!

robcbryant commented 3 months ago

As an addendum: It still seems to happen sometimes even when I make a contiguous polygon in the tilemap. Rarer--but still occurs. The issue seems to be with more extravagant angle changes, e.g. moving from a horizontal plane to a 45 degree incline is fine, but if it's closer to 67.5 degrees (even with the slope setting for the chracterbody2d set to 75 degrees) It will still often get snagged. If I stop moving at this point and then move again, it will work. The general issue is that it doesn't seem to be possible in the referenced build to mimic a Sega Genesis Sonic the Hedgehog slope attachment and smooth movement at angles larger than 45 degrees or angles that the difference between the previous bottom collider and new collider are greater than 45 degrees. I am using a rectangle collider. So honestly it might work better using a capsule like collider. But the expectation is that a simple rect collider would still work unless I completely misread/forgot the documentation.

Sorry for bringing it up again. There are ways I can sidestep the behavior further, but it will involve redesigning some pathways. Which is fine.

Best!