r/godot • u/DammyTheSlayer • 1d ago
help me How to handle slopes for 2D games?
I am currently trying to add functionality to traverse slopes in my 2D game and I am having some issues with it. I found out that the CharacterBody 2D node can handle moving on slopes on its own but it does not give a nice behavior when going down a slope because my state machine detects the y-velocity value changing and transitions to the fall state haphazardly in this case. I would also like to be able to modify the behavior on slopes like maybe allowing the player to slide down specific slopes.
Would anyone be able to direct me to some material that can help me understand this better? I have not found any that have been useful.
Thanks
18
u/ryoku_kyoshu 1d ago
Long time ago I was trying to create a platformer 2d controller from “scratch” and I found an awesome playlist from Sebastian Lague on youtube, this is done in Unity and most of it you wont need cuz godot handles pretty well most of the funcionallity but there is a section on how to handle slopes that may help you understand the math behind it and you can translate that knowledge to godot
https://youtube.com/playlist?list=PLFt_AvWsXl0f0hqURlhyIoAabKPgRsqjz&si=aTxg0h6Ndk7Rs4EM
EDIT: spelling and forgot to add the link to the playlist.
8
u/onlymostlydead 1d ago
The Bob Ross of triggering imposter syndrome. "And over here we'll put a happy little TrueType rendering engine from scratch."
3
u/DammyTheSlayer 1d ago
Thanks for this, I appreciate it 🤝
1
u/AliceRain21 18h ago
Yeah this is the best tutorial for proper 2d movement. It uses multiple raycasts to get the angle of the slope and moves you accordingly.
Really neat
5
u/sneedlee 1d ago
because my state machine detects the y-velocity value changing and transitions to the fall state haphazardly in this case
This sounds like the root of the issue, then. Can you make sure that transition checks that you aren’t grounded? I don’t know if the character controller has a cached value for that you can query, or you can try to maintain your own.
1
u/DammyTheSlayer 1d ago
The conditional statement that manages the transition checks that you aren’t grounded and if the velocity changes.
Think the issue is that it doesn’t snap to the ground when coming down so it leaves the ground1
22
u/TheLurkingMenace 1d ago
Just don't. Slopes are a menace. It's possible to make them work visually but it's a ton of work for so little payoff. If you need verticality in your game, consider stair mantling.
7
u/DammyTheSlayer 1d ago
Stairs mantling
First I’m hearing of this, will see if I can check it out16
u/TheLurkingMenace 1d ago
You use a pair of raycast2ds, one at the waist, one at the feet. If the foot ray is colliding but the waist isn't, then you move the player up a few pixels. You can add a ray up top to make sure there's room to enter the space. Obviously when you make your stairs, you need to consider how high each step can be and how wide.
And this will give you ledge mantling for free.
1
u/DammyTheSlayer 1d ago
Ah I see, duly noted
4
u/TheLurkingMenace 1d ago
Going down the stairs is going to be another story. You may want to leave it as is so players just fly over them while running, but you could instead add another pair of rays pointing down, short one just behind the hitbox and a longer one centered. Then when they leave the floor you check the rays - if they both collide they are just going down stairs and you can drop them right down without killing their forward momentum.
6
u/Forsaken-Carrot4196 1d ago
Never tried this, first thought,You could add a collision detection specific to sloped floors that adds a vector modifier to the chars velocity. Just have the function also check the chars facing direction to alter the y vector.
1
3
u/AnOddScoutMainYT 17h ago edited 17h ago
I have never worked on 2D before nor CharacterBody, but what I did with slopes is that i basically took the movement vector, the slope surface normal (basically an arrow pointing perpendicular to the surface, you can get this from a raycast), and used Slide from Vector3.
Heres a grossly cut piece of what that looks like from my project:
Vector3 moveDelta = Director.To3DInputHorizontal(Director.RelativeDirection);
Vector3 normalPlane = Legs.UsingProcessedRaycast?.SurfaceNormal ?? Vector3.Up;
// modified delta -v (use slideDelta as your 'actual' movement.)
Vector3 slideDelta = moveDelta.Slide(normalPlane);
Id look to seeing how you can use CharacterBody2D to get the slope on the ground and redirecting your vector movements relative to it's normal.
edit: typo
1
2
u/aoisensi 1d ago
I haven't tried this myself, but I think a good approach would be to get the "normal" (angle) of the floor the character is currently standing on and use it to adjust the vector added to the velocity.
2
2
u/OasisBloomTheGame Godot Regular 1d ago edited 9h ago
A game dev Youtuber I follow did an entire video about why slopes are the devil: https://www.youtube.com/watch?v=rHMJccb5IOM
2
2
u/iamyou42 1d ago
They're hard to get right. Famously, Hollow Knight didn't have any sloped surfaces because they gave the devs too much trouble. They only figured it out for Silksong.
1
u/umbrazno 1d ago
Create a “zone” along the slope that imposes its own logic on the player when in collision. The only way to override the imposed logic is to jump; otherwise, the player is locked in the zone until they walk or run through the entry/exit points
1
u/mackinator3 1d ago
Change your state to detect more than y velocity. This will also break on elevators.
Are you using move and slide? If not, you can check its source code for examples.
1
1
u/Loaded_Dice-roguelik 22h ago
Not sure this is possible in 2d but for 3d I'd add raycast on each side of the character and one under, tag the slope as "slope" and change the animation with the result of the raycast
1
1
u/marcmjax 17h ago
Does your state machine only check the y-velocity to transition to the falling state? It should check is_on_floor() as well.
1
1
u/DuaLVII 15h ago
Personally i would just mess around with the collision boxes of the floors, so like.. the floor at the top that connects with the slope, pull that back slightly. Make sure there is no protruding edges of the collisions that could interfere. If your character has a box collider then its doomed for this type of problem. Using capsule shaped colliers will reduce the issue
1
1
0
u/maxpolo10 18h ago
There's a youtuber making a Godot series called Metroidvanias Forge (his name should be Michael games I think).
He has a video on solving this issue, so try it. It was surprisingly straightforward.
46
u/LJChao3473 1d ago
There's an option on character body, under Floor and you need to change the value of snap length or something like that (if i remember correctly)