# How to make the player slide smoothly against terrain

I'm making an isometric game. When the player tries to walk diagonally into a wall I want them to slide smoothly across it, so whatever portion of the movement would be legal is used, and anything in the direction of the normal is thrown away. Walls can be any angle, not just vertical or horizontal, and the player has 360 motion.

I feel like I'm almost there but I can't put the last piece into place.

Update: great news everyone! I have it working. But... I'm a bit confused what I should be normalising and what not. The normal just needs to be a unit vector, right? but then I'm mixing that with my input so I'm normalising that - am I wrong?

By the way, I have also found that I need to push the player 1 pixel in the direction of the normal, so that they don't get stuck on things - works well.

Just project your vector of motion onto the plane normal and then subtract the result from your vector of motion.

Vector undesiredMotion = normal * (dotProduct(input, normal));
Vector desiredMotion = input - undesiredMotion;


Something like that anyway. Although in your lovely diagram the input seems to be away from the wall so I'm slightly confused.

• sorry he's supposed to be in front of a vertical wall there. terrible drawing – Iain Sep 23 '10 at 17:49
• I'm a bit confused about dot product. Isn't dot product a scalar? – Iain Sep 23 '10 at 17:54
• Yes, but you multiply it by the normal (a vector) to get the vector of your undesired motion. A vector (x,y,z) multiplied by the scalar s gets you the vector (sx,sy,sz). – Chris Howe Sep 23 '10 at 18:37
• Done, changed the variables to hopefully match the diagram. :) – Chris Howe Sep 23 '10 at 20:11
• @Iain I'm really trying to understand how to use this answer but I can't seem to grasp it. When I create this exact code I get really weird desiredMotion results. Did you ever get this working? – test Oct 12 '14 at 6:00

While it's straight forward to just remove the component of the motion that is in the direction of the normal, it may suit your gameplay to rotate the motion vector instead. For instance, in a 3rd-person action game, it may be easy to get slightly hung up on walls and other boundaries, so you can make some guesses at what the player intends.

// assume that 'normal' is unit length
Vector GetDesired(Vector input, Vector normal) {
// tune this to get where you stop when you're running into the wall,
// vs. bouncing off of it

// tune this to "fudge" the "push away" from the wall
static float k_bounceFudge = 1.1f;

// normalize input, but keep track of original size
float inputLength = input.GetLength();
input.Scale(1.0f / inputLength);

float dot = DotProduct(input, normal);

if (dot < 0)
{
// we're not running into the wall
return input;
}
else if (dot < k_runningIntoWallThreshold)
{
Vector intoWall = normal.Scale(dot);
intoWall.Scale(k_bounceFudge);

Vector alongWall = (input - intoWall).Normalize();
alongWall.Scale(inputLength);

return alongWall;
}
else
{
// we ran "straight into the wall"
return Vector(0, 0, 0);
}
}

• Nice. But if you scale by a fudge factor does that make you bump along the wall vs sliding along it, or is it just a case of tweaking it? – Chris Howe Sep 23 '10 at 20:14
• My thought is that you tweak it to look ok; certainly if it is too big it'll look like you're bouncing but if it's subtle enough it'll just keep you from getting hung up on slight bends in the surface. – dash-tom-bang Sep 23 '10 at 21:44