Walking on the roof with rigidbody movement

I believe this is something that not many people have asked for, its kinda weird I know, but the result should be awesome.

Here’s the code I have.

using UnityEngine;
using System.Collections;

[RequireComponent (typeof (Rigidbody))]

public class Player_movement : MonoBehaviour {
		
	public float PlayerSpeedWalk = 30.0f;
	public float gravitypull = 10.0f;
	public float maxVelocityChange = 15.0f;
//	public float jumpHeight = 2.0f;

	private bool grounded = false;
	private Vector3 localgravity;
	private Vector3 globalgravity;
	private Vector3 curgravitywell;
	private Vector3 direction;

	
	
	void Awake ()
	{
		rigidbody.freezeRotation = true;
		rigidbody.useGravity = false;
	}
	
	void FixedUpdate ()
	{
		
		RaycastHit hit2;
		if (Physics.Raycast(transform.position, Vector3.down, out hit2))
		{
			globalgravity = hit2.point;
		}
		
		if (grounded)
		{

			// Calculate how fast we should be moving
			Vector3 targetVelocity = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
			targetVelocity = transform.TransformDirection(targetVelocity);
			targetVelocity *= PlayerSpeedWalk;

			// Apply a force that attempts to reach our target velocity
			Vector3 velocity = rigidbody.velocity;
			Vector3 velocityChange = (targetVelocity - velocity);
			velocityChange.x = Mathf.Clamp(velocityChange.x, -maxVelocityChange, maxVelocityChange);
			velocityChange.z = Mathf.Clamp(velocityChange.z, -maxVelocityChange, maxVelocityChange);
			velocityChange.y = 0;
			rigidbody.AddRelativeForce (velocityChange, ForceMode.VelocityChange);

//			if (Input.GetButton("Jump"))
//			{
//				rigidbody.velocity = new Vector3(velocity.x, CalculateJumpVerticalSpeed(), velocity.z);
//			}

			Vector3 localdown = transform.TransformDirection(Vector3.down);
			RaycastHit hit;
			Debug.DrawRay(transform.position, localdown, Color.red);
			if (Physics.Raycast(transform.position, localdown, out hit))
			{
				transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
				Debug.DrawLine(transform.position, hit.point);
				localgravity = hit.point;
			}
			curgravitywell = Vector3.Lerp(localgravity, globalgravity, 0.25f);
			direction = curgravitywell - transform.position;
		}
		else 
		{
			transform.rotation = Quaternion.LookRotation(Vector3.forward);
			direction = Vector3.down;
		}
		grounded = false;
		Debug.DrawRay (transform.position, direction);
		collider.rigidbody.AddForce(direction * gravitypull);
	}
	
	void OnCollisionStay ()
	{
		grounded = true;
	}
//	float CalculateJumpVerticalSpeed()
//	{
//		// From the jump height and gravity we deduce the upwards speed
//		// for the character to reach at the apex.
//		return Mathf.Sqrt(2 * jumpHeight * gravitypull);
//	}
}

And it works, pretty ok, the problem is once I go past the halfway mark (where my wall starts curving over and becoming upside down) the character flips out and basically just dies. It flips out and slingshots him all over the place.

Even if I set the lerp to 0, so that global gravity should have no effect on you, it still does it. I can upload the webplayer if anyone wants to see the result of this code, or you can run it on a capsule with a capsule collider yourself.

maybe this script will work.It will walk on anything.
Note:this script was not done by me i simply googled it for you.

    var moveSpeed: float = 6; // move speed
    var turnSpeed: float = 90; // turning speed (degrees/second)
    var lerpSpeed: float = 10; // smoothing speed
    var gravity: float = 10; // gravity acceleration
    var isGrounded: boolean;
    var deltaGround: float = 0.2; // character is grounded up to this distance
    var jumpSpeed: float = 10; // vertical jump initial speed
    var jumpRange: float = 10; // range to detect target wall
     
    private var surfaceNormal: Vector3; // current surface normal
    private var myNormal: Vector3; // character normal
    private var distGround: float; // distance from character position to ground
    private var jumping = false; // flag "I'm jumping to wall"
    private var vertSpeed: float = 0; // vertical jump current speed
     
    function Start(){
    myNormal = transform.up; // normal starts as character up direction
    rigidbody.freezeRotation = true; // disable physics rotation
    // distance from transform.position to ground
    distGround = collider.bounds.extents.y - collider.center.y;
    }
     
    function FixedUpdate(){
    // apply constant weight force according to character normal:
    rigidbody.AddForce(-gravity*rigidbody.mass*myNormal);
    }
     
    function Update(){
    // jump code - jump to wall or simple jump
    if (jumping) return; // abort Update while jumping to a wall
    var ray: Ray;
    var hit: RaycastHit;
    if (Input.GetButtonDown("Jump")){ // jump pressed:
    ray = Ray(transform.position, transform.forward);
    if (Physics.Raycast(ray, hit, jumpRange)){ // wall ahead?
    JumpToWall(hit.point, hit.normal); // yes: jump to the wall
    }
    else if (isGrounded){ // no: if grounded, jump up
    rigidbody.velocity += jumpSpeed * myNormal;
    }
    }
     
    // movement code - turn left/right with Horizontal axis:
    transform.Rotate(0, Input.GetAxis("Horizontal")*turnSpeed*Time.deltaTime, 0);
    // update surface normal and isGrounded:
    ray = Ray(transform.position, -myNormal); // cast ray downwards
    if (Physics.Raycast(ray, hit)){ // use it to update myNormal and isGrounded
    isGrounded = hit.distance <= distGround + deltaGround;
    surfaceNormal = hit.normal;
    }
    else {
    isGrounded = false;
    // assume usual ground normal to avoid "falling forever"
    surfaceNormal = Vector3.up;
    }
    myNormal = Vector3.Lerp(myNormal, surfaceNormal, lerpSpeed*Time.deltaTime);
    // find forward direction with new myNormal:
    var myForward = Vector3.Cross(transform.right, myNormal);
    // align character to the new myNormal while keeping the forward direction:
    var targetRot = Quaternion.LookRotation(myForward, myNormal);
    transform.rotation = Quaternion.Lerp(transform.rotation, targetRot, lerpSpeed*Time.deltaTime);
    // move the character forth/back with Vertical axis:
    transform.Translate(0, 0, Input.GetAxis("Vertical")*moveSpeed*Time.deltaTime);
    }
     
    function JumpToWall(point: Vector3, normal: Vector3){
    // jump to wall
    jumping = true; // signal it's jumping to wall
    rigidbody.isKinematic = true; // disable physics while jumping
    var orgPos = transform.position;
    var orgRot = transform.rotation;
    var dstPos = point + normal * (distGround + 0.5); // will jump to 0.5 above wall
    var myForward = Vector3.Cross(transform.right, normal);
    var dstRot = Quaternion.LookRotation(myForward, normal);
    for (var t: float = 0.0; t < 1.0; ){
    t += Time.deltaTime;
    transform.position = Vector3.Lerp(orgPos, dstPos, t);
    transform.rotation = Quaternion.Slerp(orgRot, dstRot, t);
    yield; // return here next frame
    }
    myNormal = normal; // update myNormal
    rigidbody.isKinematic = false; // enable physics
    jumping = false; // jumping to wall finished
    }