In a lot of the examples I checked about CharacterBody3D, I’ve seen that the gravity is applied only when “is_on_floor()” returns false.
if not body.is_on_floor():
velocity += gravity * delta
Is it really the way to do it? Just a small optimization?
For most common use cases, this seems right and is working well, but in mine, it triggers an issue when moving on a curved surface with my custom gravity system (actually small planets, my gravity system updating CharacterBody3D.up_direction): “is_on_floor()” oscillate between true and false. I expected the same problem when walking down on slopes or on curved surface in static gravity conditions, but I didn’t notice anything.
I initially though of a problem with snapping function but I haven’t found a lot of information about it and couldn’t solve my problem that way.
What actually solved it without triggering any other issue is removing “is_on_floor()” check and simply applying gravity every frame.
So in practice, I no longer have any issue, everything is working as expected, but I’m questioning that practice or the way I solved my issue.
Is it wrong applying gravity that way? Did I miss something about the snapping function?
You’re encountering a similar problem to what occurs with is_on_wall(). In that case, it is only true if the player is moving towards a wall. You have an edge case. There are two options. You can make gravity always apply like you did. Or, you can use a RayCast2D opposite of the UP direction to determine when to apply it.
I recommend considering using the Area2D gravity override properties. Then you can just use get_gravity() and apply it. What you’re doing is likely not causing the problem you’re seeing, but it might be, and it might cause other unforeseen problems in the future.
I’m working in 3d, but it is exactly what I’m doing. Are the Area2D/Area3D gravity override system supposed to automatically update the up_direction? I maybe should make another try not updating it manually.
Anyway, if there isn’t any problem with applying gravity all the time, I think I’ll stick with that solution.
I took a look at up_direction again and it looks like there’s nothing wrong with updating it. It determines what is a floor, wall and ceiling. Personally, I use is_on_ceiling() instead of inverting it, but it makes sense with what you described.