Rotate vector A around vector B until it is perpendicular to vector C

I am creating a custom character controller that uses rigidbody physics to move around. At the moment, I can accurately calculate an acceleration vector that will move the player around, based on their inputs (WASD, shift, control), on the horizontal plane. The problem I am trying to overcome now is how to get them to move up and down slopes realistically. At the moment, the acceleration vector is only horizontal. What I am trying to do is get the normal of the terrain plane that the player is standing on (C), and rotate the acceleration vector (A) around the player’s local x axis (B) until it is perpendicular to the normal (C).

I’m pretty sure the solution will involve cross/dot products but if this is a solved problem, there is no point me burning brain cells over it!

Well, that’s actually pretty easy :wink: Just do those 3 steps:

  • project your acceleration vector onto the (normalized) ground normal.
  • subtract that projected vector from your acceleration vector
  • normalize the result and multiply it with your original length.

Something like that:

Vector3 AlignToGround(Vector3 groundNormal, Vector3 acceleration)
    //groundNormal.Normalize(); // usually the surface normal is already normalized if not this line is needed
    var V = Vector3.Project(acceleration, groundNormal);
    V = acceleration - V;
    return V.normalized * acceleration.magnitude;

Thanks for your answers, here’s how I ended up doing it.

		Vector3 velocityRightVector = Vector3.Cross(hit.normal, rb.velocity);
		Vector3 newVelocityVector = -Vector3.Cross(hit.normal, velocityRightVector);