Projecting Velocity Along a Surface

My character, as a dynamic object, always gets stuck on walls if I jump while moving toward them. Even YoFrankie had the same issues.

I partially solved this by casting a ray in the direction of my player’s velocity. It sets my player’s linear velocity (x and y) to zero if a wall is detected. This solves one problem: now the player will smoothly slide down walls. For a complete solution, however, I need the player’s velocity to be projected along the surface of the wall, not just changed to zero. This crappy illustration demonstrates the desired result.


I’m a little rusty on the linear algebra, so I would just like a little help on how to get the green projected vector, given the player’s velocity (red) and the wall surface normal (yellow) obtained from KX_Game_Object.rayCast(). This is a 2-Dimensional operation because I let gravity worry about the player’s Z velocity.

I know about Vector.project(), I just don’t know the fastest way to get that green vector to project on in the first place, given the normal and my player’s velocity. Help?

Just increase the friction of the characters’s and the wall’s material.

Align the player to the wall surface, a constrain actuator can do that! Or a align to axis function!

Just increase the friction of the characters’s and the wall’s material.

Increasing the friction has quite the opposite of the desired effect. Decreasing the friction still does not prevent the character from getting stuck on walls when jumping into them. BGE physics are too wonky to trust anyway, which is why I’m opting for a cold-cut-code solution.

Align the player to the wall surface, a constrain actuator can do that! Or a align to axis function!

I do not necessarily want to align the player to the wall surface because the human player did not ask to be rotated upon hitting a wall and will be furious. I just need the velocity to be re-projected along the wall. More importantly, how on earth do I get the vector to constrain my player’s axis/orientation to in the first place? That was my original question.

Perhaps I have not been too clear. Let’s pretend you’re playing an FPS and you walk toward a wall, striking it at a 45 degree angle from the wall’s surface. You will then be moving along the wall, not as fast as before. The steeper your approach to the wall, the slower you’ll slide along it. Given two vectors, the player’s velocity and the normal of the wall, what’s the most efficient way to find the third vector that points along the surface of the wall?

I thought of a solution last night, and I don’t know if it’s the best way to do it, but I also don’t know why I’m asking anyone in the BGE forums for advice on practical linear algebra.

If I take the cross product of the Red and Yellow vectors (in that order), I’ll get a third vector (call it C). If I then take the cross product of Yellow x C, I’ll get the Green vector. I can then use RedVec.project(GreenVec) to get my final result.

hit_obj, hit_pt, hit_norm = player_obj.rayCast(player_vel, None, 0.5)
cross = player_vel.cross(hit_norm)
surface = hit_norm.cross(cross)
final_vel = player_vel.project(surface)

If anyone has a better solution for getting this vector, I would be very pleased to hear it. This kind of math universally comes in handy, whereas all game engines are different in their own handling of physics.

Theoretically the play just moves along the wall, perpendicular to the normal.
You could take the linearVelocity and change the bearing, but im not sure how one would mathematically determine the rate of slowing of the character; As i’m not sure what that depends upon.

It sounds perfectly correct to me.
Probably the same result could be obtained by subtracting from Red its projection on Yellow, i.e.:

final_vec = RedVec - RedVec.project(YellowVec)

But I’m not sure, since I did not test this solution…

Brilliant and much, much simpler.