I've been trying to wrap my head around this issue: in a 2D platformer game (but this may as well apply to 3D games) I want the character to "stick" to the surface that it's moving along and at the same time maintain the same velocity no matter the incline/decline of the current surface. Also, if my character's speed is 1 unit/sec and the current delta time is 0.25, I want it to travel exactly 0.25 units no matter the "shape" of the surface met along the way during the frame.
Naively, I started with this base logic (warning, pseudo-code incoming):
vel += acceleration * timeDelta;
movementDelta = vel * timeDelta;
hit = raycast(pos, downward);
if (hit)
{
vectorAlongSurface = hit.normal * fancyLinearAlgebra;
pos += vectorAlongSurface.Normalized * movementDelta.Magnitude;
}
else
{
pos += movementDelta;
}
But this is correct only if my character moves along the same surface normal for the whole frame and it breaks pretty badly if during the frame the surface has different normals along the way. This can give the feeling that the speed at which the character is moving is inconsistent. To give you an example:
While I do expect answers like "just don't make your terrain like that" I'm also considering situations where my game might experience an unexpected lag and have to deal with a large time delta that might push the character through different surface normals during the same frame.
Any advice on how to properly handle this would be much appreciated. I was thinking about somehow tracing all the changes of surface inclination from the character's position to the "naive raycast hit" point, but that seems to be quite expensive, especially considering that all the enemy characters would have to do the same. There must be some simple solution to this that I'm not seeing. Or maybe there's a way to make the inconsistency of speed in the given example less noticeable/irrelevant?
Thank you guys.