Is_on_floor() is sometimes weirdly detecting the wall as a floor

Godot Version

4.2.1

Question

So, I’m pretty new to Godot. I’m using is_on_floor() and is_on_wall() to detect whether or not my character is grounded or wall-sliding, and I’ve encountered an issue where if the character runs into a hole just slightly bigger than itself, is_on_floor() continues to output true, even though the floor normal is completely horizontal and identical with the wall normal, which to my understanding shouldn’t be possible. My floor_max_angle is the default. Through testing I’ve figured out that for this bug to happen, leaving the floor and coming into contact with the wall need to happen on the same frame.

ezgif.com-video-to-gif-converter

This mostly only happened if I applied gravity to the character in a grounded state as well as in the air, while switching to only applying it while in the air seemed to fix it, though I found out it was still possible by coming off a one-way platform in just the right way. Through testing, I found that by changing the floor_snap_length to be bigger, the descent down the wall was faster, and that through get_real_velocity() the downward velocity was always the same as the physics framerate.

Also, in certain parts of the level this weird walking down the wall only goes on for exactly one tile (100px) before correcting itself, while in other spots it continues indefinitely and doesn’t stop. No clue why, they’re functionally identical from what I can see.

Despite searching a lot, I haven’t found any mention of anything like this. Does anyone know what’s happening here?

1 Like

You can try several things:

  • Make your KinematicBody’s collision smaller or square-shaped.
  • Use Raycasts instead of is_on_floor.
  • Slow down your character.
  • Increase the gravity of your character.

Thanks, I’m aware there are workarounds like that, and yeah, I might have to switch to some other method for detecting groundedness than relying on is_on_floor(), but what I really want to know if this is an actual bug in the engine that others may have encountered or if anyone knows a real reason for why it’s happening or a fix that isn’t just a workaround. I think it’d be a shame to immediately abandon this method since it has a lot of cool features built in, but I also don’t want to rely on something that I don’t really understand or control.

1 Like

Actually I just realized that even if I did switch to using raycasts for floor detection, this bug would still probably happen, because the physics engine would still consider the character to be grounded and not let it fall properly…

Surely other devs have encountered something like this before? I don’t know what to do, I don’t want to just change the collision shape or character size and hope that it doesn’t happen again, I won’t be able to make the game I want if I start going down that lane. :frowning:

2 Likes

Hi Liero, im currently facing the exact same issue as you. I’m trying by my own to fix this, but it is such a pain to resolve it :face_with_spiral_eyes: :hot_face:.
If i manage to fix that, i’m going to share with the solution with you.

1 Like

I had opened an issue which may be related. When Camera is enabled, the ParallaxLayer/Tilemap Physics Layer is calculated inaccurately using is_on_floor() · Issue #88752 · godotengine/godot · GitHub

1 Like

I figured out what my problem was. I’ve setted up animations in my animation player in which I changed the vertical size of my player’s collision shape. So when player was falling, the collision shape shrinked.
I’ve solved that issue by reverting the collision shape size to the same value as the one setted for the idle state (I’m using a finite state machine), and now everything works fine.

Hope this will help you resolve your problem.

I’ve got another issue that is very close, but i’m not using parallax layer yet.