Zero Gravity Racing Game Controls

Hello. I’ve been trying to implement a racing game where the track loops all around. For the vehicles, gravity points them towards the track so that they can move along them even when said track is upside down or vertical.

Here is the control script I have so far…

function foo3(){

	// Translate.
	var move : Vector3;
	
	
	move = transform.forward*Input.GetAxis("Vertical")*Time.deltaTime*speed;
	transform.Translate(move);
	
	
	move = transform.right*Input.GetAxis("Horizontal")*Time.deltaTime*speed;
	transform.Translate(move);
	
	// Rotate.
	var dirForward:Vector3 = transform.TransformDirection(Vector3.forward);;
	var down : Vector3 = transform.TransformDirection(Vector3.down);
	var range : float = 50;
	var hit : RaycastHit;
	
	
	// Raycast to hit the track.
	down.Normalize();
	Debug.DrawRay(transform.position, down*range, Color.red);
	if(Physics.Raycast(transform.position,down,hit,range)){
		if(hit.collider.gameObject.tag == "race_track"){
			//print("hit track...");
            Debug.DrawRay(hit.point, hit.normal, Color.white);
            
            // Cross w/ the track normal to find our new forward.
            dirForward = Vector3.Normalize(Vector3.Cross(transform.right,hit.normal));
			if (dirForward != Vector3.zero) {
			    transform.rotation = Quaternion.LookRotation(dirForward);
			}
	
			// snap us to our track position.
			var newPos : Vector3 = hit.point + hit.normal*5;
			transform.position = newPos;
			print("newpos: " + newPos);
		}
	}
	
    Debug.DrawRay(transform.position, transform.forward, Color.white);
}

However, this doesn’t work as I’d like it to. The vehicle won’t move past a vertical direction into an upside down one. It will just sit at a perfectly vertical direction.

Does anyone have any ideas as to how to solve this? Has anyone seen this question asked before (i’d definitely take an existing solution if it already exists)? Thanks for your time.

update:
So after debugging some, I’ve found out that when the vehicle becomes vertical and the forward direction is (0,-1,0), the vehicle moves towards it’s own relative (0,-1,0) as in down. I’m going to try to fix this so that it uses the absolute (0,-1,0).

update:
Making the translation absolute fixed the problem stated above. However, now once a vertical direction is reached, the down direction flips 180 into the up direction and the ray cast from the vehicle to the track never hits. I’m not too sure how to construct the down vector differently. I’ll try casting both down and up, and test with either that hits.

update
Well ray casting down and up makes the vehicle “catch” the track for sure but… It doesn’t solve anything. Once it reaches a vertical direction the vehicle flips onto it’s head. I was able to solve this by checking out this post: http://forum.unity3d.com/threads/89343-Camera-rotation-stop-the-flipping. I then changed my code…

// old.
			    transform.rotation = Quaternion.LookRotation(dirForward);
// new.
			    transform.rotation = Quaternion.LookRotation(dirForward,transform.up);

What this did is (I believe) set the rotation to use my vehicles relative up.

I hope this post is helpful to anyone who runs into these problems.

For completeness I’m posting the answer here outside of the original question.

The rotation to the new forward direction needed to use the up direction of the vehicle itself. I discovered this here: http://forum.unity3d.com/threads/89343-Camera-rotation-stop-the-flipping.

// old.
             transform.rotation = Quaternion.LookRotation(dirForward);
// new.
             transform.rotation = Quaternion.LookRotation(dirForward,transform.up);