How to calculate the 3D vector perpendicular to a polygon surface in a specific direction

I’m creating an asteroid mining game in Unity 3D, where “down” is the center of the planet you are on (So I am mostly using local rotations when dealing with vectors). I have a working physics-based character controller, but it has problems dealing with slopes. This is because when I add a force to the character, currently it pushes along the player’s forward vector (see picture). What I want to do is calculate the vector that is parallel to this terrain surface, but in the direction that the player is facing (so that the player can move up the slope).

I originally thought that i could just find the vector perpendicular to the normal, but then how do I know which direction it will be in. Also complicating matters is the fact that the player could be oriented in any way in relation to the global x, y, and z.

Either way, I have the surface normals of the terrain, I have all of the player’s directional vectors, but I just can’t figure out how to put them all together. I can upload code or screenshots of the editor if necessary. Thanks.

There are multiple ways you can approach this, so here’s an example of one of them:

Because you know your basic “down” vector as well as the normal of the surface you want to walk on and you know your character’s basic facing, a few Cross Products can convert your character’s facing to align with the ground.

// You mention having both of these already, so I'm glossing over their definitions
Vector3 upVector = (playerTransform.position - asteroidTransform.position).normalized;
Vector3 slopeUpVector = slope.normal;

// This will likely result in the same value as playerTransform.right
// If you've done everything right already, then you won't need these two lines
// However, substituting "player" with "camera" can provide axis-aligned vectors
// for an otherwise non-level camera, so it's good to keep in mind
Vector3 currentForward = playerTransform.forward;
Vector3 playerRight = Vector3.Cross(upVector, currentForward);

// Finally, get the cross product using the player's "right" and the normal of the slope
Vector3 newForward = Vector3.Cross(playerRight, slopeUpVector).normalized;

To note: without any sanitation in place, this can fail when the player’s forward direction is 100% parallel to the current up/down vector.