Thank's a lot Bunny83, your answer put me into the right direction.
Finaly I got it working. Just in case any of you want to have a look at the code, here it is. If you have any suggestions on making it simpler, just tell me. I'm still new to unity.. :)

using UnityEngine;
using System.Collections;
public class Walker : MonoBehaviour {
public float speed = 0.02f;
public float maxWorldRotationSpeed = 2f;
public float maxRotationSpeed = 10f;
private CharacterController controller;
private RaycastHit hit;
private Vector3 moveVector;
private GameObject geometry;
void Start () {
//get character controller and mesh for animation controls
controller = GetComponent<CharacterController>();
geometry = transform.Find("geometry").gameObject;
}
void FixedUpdate () {
//get all Inputs
Vector3 directionVector = new Vector3(Input.GetAxis("Horizontal"),0 , Input.GetAxis("Vertical"));
if(directionVector != Vector3.zero){
//we are walking
geometry.animation.CrossFade("walk");
//rotate the direction vector to the characters rotation
Quaternion inputTransformRotation = Quaternion.LookRotation(Vector3.forward, transform.up);
directionVector = inputTransformRotation * directionVector;
//add speed
moveVector = directionVector * speed;
//cast a ring around the character to get collision informations
//check the Ringcast function for more details
if(Ringcast(transform.position,transform.localScale.y/2+0.2f,16,out hit,Vector3.Cross(transform.up,directionVector),1<<10)){
if(hit.collider.tag == "walkable"){
//we can walk on the thing we hit
//calculate new up vector lerping to the walkable colliders normal, so the character walks head up
Vector3 newUp = ConstantSlerp(transform.up,hit.normal,maxWorldRotationSpeed);
if(Vector3.Angle(newUp,transform.up)==0f){
//character allready walks head up
controller.Move(moveVector);
}else{
//character needs to turn
//wee need to create a plane, to check our distance to the walkable collider. for walking up a wall we have to turn before we pass it, for walking down a wall we have to turn after we pass it.
Vector3 wallNormal;
//get the normal of the plane, so the normal points away from the character
if(Vector3.Angle(hit.normal,directionVector)<90){
wallNormal = hit.normal;
}else{
wallNormal = -hit.normal;
}
//create the distance plane. as soon as the distance on next move is 0, we have to turn
Plane wall = new Plane(wallNormal,hit.point+hit.normal*(transform.localScale.y/2+0.01f));
float distance = Mathf.Abs(wall.GetDistanceToPoint(transform.position));
if(distance-moveVector.magnitude<=0){
//move the character to the plane
if(wall.GetSide(transform.position)){
controller.Move(-wallNormal*distance);
}else{
controller.Move(wallNormal*distance);
}
//rotate the character to the new up vector
Vector3 forwd = Vector3.Cross(transform.right,newUp);
transform.rotation = Quaternion.LookRotation(forwd, newUp);
}else{
//move normal if the distance to the turning plane is too big
controller.Move(moveVector);
}
}
}
}
// Set rotation of the character to the move direction (same as in Platform Input controller)
if (directionVector.sqrMagnitude > 0.01) {
Vector3 newForward = ConstantSlerp(transform.forward,directionVector,maxRotationSpeed);
newForward = ProjectOntoPlane(newForward, transform.up);
transform.rotation = Quaternion.LookRotation(newForward, transform.up);
}
}else{
//the character doesnt move
geometry.animation.CrossFade("idle",0.1f);
}
}
bool Ringcast(Vector3 castCenter, float castRadius, int castSteps, out RaycastHit hit, Vector3 castAxis, int castLayerMask){
//Ringcast lets us cast a ring around any axis and get the first collider we hit
float castLength;
Vector3 rotationOffset = transform.position;
Vector3 castVector;
Vector3 castFrom;
Vector3 castTo;
//set up axis
castAxis = castAxis.normalized;
//set up rotation around axis
Quaternion stepRotation = Quaternion.AngleAxis(360/castSteps,castAxis);
//set up start point of the first raycast
castFrom = castCenter + Vector3.Cross(transform.up,castAxis)*castRadius;
//draw fancy stuff into the editor window ;)
Debug.DrawLine(castCenter,castFrom);
//rotate the first point to get the target point of the first raycast
castTo = stepRotation * (castFrom-rotationOffset)+rotationOffset;
castVector = castTo - castFrom;
castLength = castVector.magnitude;
//do as many raycasts as needed
for(int i=0;i<castSteps;i++){
if(Physics.Raycast(castFrom,castVector,out hit,castLength,~castLayerMask)){
//if theres any hit return true
return(true);
}
//draw more fancy stuff into the editor window!
Debug.DrawLine(castFrom,castTo);
//rotate again and set up for the next raycast
castFrom = castTo;
castTo = stepRotation * (castFrom-rotationOffset)+rotationOffset;
castVector = castTo - castFrom;
}
//if theres no hit set it to default and return false
hit = default(RaycastHit);
return(false);
}
Vector3 ProjectOntoPlane (Vector3 v, Vector3 normal) {
return v - Vector3.Project(v, normal);
}
Vector3 ConstantSlerp (Vector3 start, Vector3 to, float angle) {
float step = Mathf.Min(1, angle / Vector3.Angle(start, to));
return Vector3.Slerp(start, to, step);
}
float ConstantSlerp (float start, float to, float vel){
float step = Mathf.Min(1, vel / (to-start));
return Mathf.Lerp(start,to,step);
}
}