I wrote a Rigidbody based character controller that mimics the standard character controller pretty well. I can't use the standard character controller because i need to change gravity and i need the capsule collider's up vector to change accordingly.
My basic setup:
In the scene a i have a character with my PhysicsController ( http://pastebin.com/Bfxn78wk ) and SimpleMotor ( http://pastebin.com/kKA8kZb2 ) scripts attached. It also has a capsule collider and a rigidbody.
This all works fine. But when jumping onto a 90 degree wall my character will collide and stay. I need a way to slide or avoid steep surfaces. I'd prefer to not do this without a raycast, i was thinking some magic code checking the collision surface normals inside OnCollisionStay and OnCollisionEnter but for the life of me i can't figure out how to approach this.
Any ideas? Maybe some code snippets?
I guess your character is always rotated in a way that the local (-y) if the gravity vector, right? With Transform.InverseTransformDirection you can bring any world aligned direction into local space of your character (which represents the current world axis ;). at least the up vector).
Just calculate the dot-product between your up-vector and your hitnormal. If both vectors are normalized the resulting value will be the cosinus of the angle. If you stand on a plane surface both vectors point in the same direction--> dotproduct == ~ 1 --> angle is 0. You can setup a reference value (cos(45)) to check if the value is greater or not.
If you want to slide down you can calculate a "sliding vector" which is just a tangent vector that points along the surface. I've done something like that already but for the CharacterControler. It should be almost the same.
CrossProduct between up-vector and surface normal and you get the tangent vector that points to the right.
Another CrossProduct between our right tangent and the surface normal and you get the sliding vector.
Finally don't forget you work in local space. If you want to apply forces you might need to transform it back to world space.
That should be all ;)
I hope that helps a bit.