Corner Correction (like in Celeste)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Kanor

I’m making a 2D platformer, with tilemaps and kinematic rigidbodies.

In Celeste, if you hit a block from below by just a pixel, your character will actually be moved sideways to slide up the block as if you hadn’t collided from the bottom, with no loss of speed. This is a nice quality-of-life mechanic and I really want it in my game. Does anyone have any ideas on implementing this?

:bust_in_silhouette: Reply From: Bernard Cloutier

I haven’t tried doing that, but Celeste’s devs have actually shared their player controller code 2 years ago, it’s on github. It’s an XNA game and it’s written in C#, so you’ll need to convert some code, but the logic should stay the same. Looks like this part is what you’re looking for.

The nested for loops are a bit confusing, but here’s what I understand: the first for loop goes from i = 1 to DashCornerCorrection, which is 4. So they’ll check at 4 different heights. The innerloop will run twice each time (unless a clear path is found), once with j = 1, and once with j = -1. So basically the 4 different heights will each be checked twice, one time positive, one time negative, for a total of 8 height checks (4 above the character, 4 below). The first height check which results in no collision will be selected. This code handles correcting from below, but if your char is hitting its head on a platform, it’ll move it below the platform instead (unless the top of the platform is closer).

I’ve just noticed that this was specifically for the dash move. There is another corner correction check that doesn’t handle collision correction from above.

Thank you for this code and the links! For anyone who wants to know my conclusions, here they are:

Corner correction is only done in the player’s favor (a.k.a upwards for jumps) so should only happen if the player is moving upwards, and you can tell something is above them.

  1. You usually want to do corner correction BEFORE you hit the ceiling, so you can keep the velocity. A raycast would work, or you could save velo before you ever use move_and_slide and restore the old velo if it hits a ceiling that fits the conditions for corner correction.

  2. Corner correction should only be done in the direction the player is moving (left or right), unless the player is standing still, in which case both directions are fine.

  3. Celeste does corner correction by testing (a raycast would probably work best in our case) if there is no block upwards if the user were to move left or right and then moves the player as far as it takes to get out from under the block, and a LITTLE BIT UP.

Dash corner correction does the same thing except rotated 90 degrees.

Dash corner correction also works downward-diagonally, but what it does is auto-land on platforms you just barely dashed past, assuming you were dashing downwards in an attempt to reach them.
Once again, to work in the players’ favor in cases of tight platforming.

Kanor | 2020-09-23 21:56