Week 45: Rotating the character to match surface slope

An animated GIF showing the character sprite and collision boundary moving smoothly around surfaces and corners with the position and rotation updating to match the surface angles.
The character now rotates to match the surface!


tl;dr: I added support for rotating the character to match the surface slope.


What happened last week?

Highlights

  • It was another short week, because I was visiting family and still dealing with colds.
  • I mainly just added support for rotating the character according to the slope of the current surface.

Laundry list

  • Fix an issue with how is-rounding-corner surface-state logic would incorrectly assume the contact point is the corner point, even if the surface is not axially aligned, and the character doesn't touch the corner.
  • Add additional verbose logs for debugging is-rounding-corner logic.
  • Add a new flag to SurfaceContact for tracking which mechanism caused the contact to exist.
  • Add a method for skipping the current CharactorAnimator blend.
  • Track character animator latest/current blend duration.
  • Finish implementing character-animator rotation to match surface-contact normal.
  • Add support for calculating the surface contact point without using Godot's collision APIs.
  • Update nav-preselection character-prediction-phantom rotation to match the contact-normal for the underlying surface.
  • Fix an issue where surface-grabs weren't triggering while still holding the jump button.
  • Debug an issue with redundant waypoint calculations with oddly-shaped surfaces.
  • Add support for edge-trajectory waypoints around surface-interior protrusions.

Rotating the character to match surface slope

Last week I added support for rotating the character in order to match the slope of the surface that they are attached to. I needed to iterate over a few different attempts before I got this to look right. The following screenshots illustrate this process.

Sorry about the jitter in some of these! It seems to be a bug in my screen-recording software when running in full-screen mode.

An animated GIF showing the character rotation not following surface angles.
  • Here is what the character looked like before.
  • The green pill-shape represents the character's collision boundary.
  • My new rotation updates only affect the actual cat image ("sprite")—the collision boundary is unchanged.

An animated GIF showing the character with a rotation that matches the surface angles, but with a position that leaves it not attached.
  • First, I updated the sprite rotation.
  • This bit was easy, since I was already tracking contact points and surface normals.
  • However, notice how the character isn't positioned correctly after rotating—they are sometimes floating a little bit away from the surface.

An animated GIF showing the character rotation and position matching the surfaces, but with a pausing problem around corners.
  • Next, I corrected the character position, according to the current rotation.
  • This mostly involved some simple trig, in order to calculate the distance according to the current angle.
  • I also needed to update how I had defined the origin for the various character poses.

An animated GIF showing the character rotation and position matching the surfaces, but with a pausing problem around corners.
  • However, after fixing the position, I noticed a problem when the character moves around corners.
  • Even though the collision boundary is moving smoothly, the contact point is static for a brief period when rounding a corner, and the sprite position pauses during this period.

An animated GIF showing the character position and rotation following the surfaces, and the position still updating when rounding corners, but with some mis-alignment of the sprite with the actual collision boundary.
  • In order to fix the sprite pause when rounding corners, I first tried averaging the sprite position between a value from the collision boundary position and the previous value from the surface-contact normal.
  • This made the sprite movement look a little better around corners, but this resulted in the sprite not being centered well on the collision boundary.

An animated GIF showing the character sprite and collision boundary moving smoothly around surfaces and corners with the position and rotation updating to match the surface angles.
  • My final solution was to interpolate the sprite's rotation and position according to the collision-boundary-center position relative to the corner point.
  • In order to interpolate the rotation, I needed to determine the surface normal immediately before and after the corner.

What's next?

  • Debug some remaining issues with oddly-shaped surfaces.
  • Finish some other surface-parsing logic I'd left-off on before.


🎉 Cheers!


This is a simple icon representing my sabbatical.

Comments