Sorry, I had to add the code as a second answer. I realized my usual login isn't registered, so I couldn't use it on a different computer, and just decided to properly register a new ID this time (and lose my precious few medals, blah!).
Here's a variable I would use to grab and hold onto the last known collision normal.
private Vector3 hitNormal;
Here's the code I use to grab hit normals of an attached CharacterCollider.
void OnControllerColliderHit(ControllerColliderHit hit)
{
Debug_Text.guiText.text = "Collision normals: " + hit.normal;
hitNormal = hit.normal;
}
Any time the character controller collides, it will report the hot normals to my GUI Text.
Debug_Text is just a variable I have declared at the top of my script.
public GameObject Debug_Text;
It's public so I can just drag and drop the GUI Text into it (I make most of my variables public just out of laziness!).
Okay. So if you play with that, you'll see on-screen what the hit normals look like whenever the attached controller collides with something. What you want to pay attention to is the X and Z coordinates. They'll range from -1.0F to 1.0F depending what angle they're colliding with the monsters.
Applying dynamic motion is now stupid-simple from here. :D Plop this single line of code wherever you want the motion to occur (probably inside an Update). I use SimpleMove rather than Move because in this case you probably want gravity to take effect. If you don't, use Move instead.
gameObject.GetComponent<CharacterController>().SimpleMove(new Vector3(hitNormal.x * Time.deltaTime, 0, hitNormal.z * Time.deltaTime));
What that code does: Finds the CharacterController attached to the game object that this script is attached to. Orders movement. Orders it to move in the direction of the hit normal X value (stored in hitNormal.x), no Y value, and the hit normal Z value (stored in hitNormal.z).
Is that more helpful?