Basic Self-Right for Rigidbody Hover Ship

Hey all, having issues trying to sort out self righting for a ship that tilts as it flies left and right. Here’s my script for flight and tilt so far, but I can’t figure out how to get it to self right.

As far as I know I have to find World up and get the ship’s up to head for it… my attempt is left in and commented out as it doesn’t work… See for yourself!

var sideSpeed : float = 10.0;
var flySpeed : float = 5.0;
var tiltSpeed : float = 5.0;

function Update () {

	var Horiz : float= Input.GetAxis("Horizontal")*sideSpeed;
	var Tilt : float = Input.GetAxis("Horizontal")*tiltSpeed;
	var Vert : float = Input.GetAxis("Vertical")*flySpeed;
	
		transform.Translate(Horiz*Time.deltaTime,Vert*Time.deltaTime,0);
		
		var shipModel : GameObject = gameObject.FindWithTag("shipModel");
		
		shipModel.rigidbody.AddRelativeTorque (0, 0, Tilt*Time.deltaTime);
		
		var angle = Vector3.Angle(shipModel.transform.up, transform.up);
		
		
		if(angle > 30){
		
		//head for world upright!! how?? this attempt is wrong -
			//shipModel.rigidbody.AddRelativeTorque (0, 0, -angle);
			

		}
}

Any help much appreciated as always!

Cheers

Will

This is essentially what you want:

var selfRightingTorque = 1.0;

// Remember to use FixedUpdate when applying continuous forces or torques!

function FixedUpdate()
{
	var angle = Vector3.Angle(transform.up, Vector3.up);
	if(angle > 0.001)
	{
		var axis = Vector3.Cross(transform.up, Vector3.up);
		rigidbody.AddTorque(axis * angle * selfRightingTorque);
	}
}

You’ll need to either set selfRightingTorque and the rigid body’s angular drag appropriately to prevent oscillation or do something cleverer to detect when you’re going to overshoot the correct orientation and apply the opposite torque pre-emptively.

Hi Neil

thanks so much for your reply, Vector3.cross rings a distinct bell and is definitely what i’m after, I bow to your knowledge of course, but i’m a bit unsure what is wrong - I’ve applied your code so I now have this -

var sideSpeed : float = 10.0;
var flySpeed : float = 5.0;
var tiltSpeed : float = 5.0;
var selfRightingTorque = 1.0; 

function Update () {

	var Horiz : float= Input.GetAxis("Horizontal")*sideSpeed;
	var Tilt : float = Input.GetAxis("Horizontal")*tiltSpeed;
	var Vert : float = Input.GetAxis("Vertical")*flySpeed;
	
		transform.Translate(Horiz*Time.deltaTime,Vert*Time.deltaTime,0);
		rigidbody.AddRelativeTorque (0, 0, Tilt*Time.deltaTime);
		
}

function FixedUpdate() 
{ 
   var angle = Vector3.Angle(transform.up, Vector3.up); 
   if(angle > 0.001) 
   { 
      var axis = Vector3.Cross(transform.up, Vector3.up); 
      rigidbody.AddTorque(axis * angle * selfRightingTorque); 
   } 
}

I’ve tried simplifying this as much as possible, trying torques and relativetorques but at the moment its just wobbling and floating.

I’ve even simplified this down to a cube in a new scene, with a rigidbody with no gravity… See for yourself if you get a moment. Thanks again for your help :slight_smile:

Cheers

Will