Rigidbody-based spaceship?

Hello!

I am working on a unique racing game set inside anti-gravity tunnels. My player can yaw with the “horizontal axis” and pitch with the “vertical axis”. The player accelerates in the direction their ship is facing with “left shift”. All rotation on the z axis is locked at zero. Here are my problems, my player doesn’t accelerate in the direction that the ship is facing, locking the RigidBody’s rotation does not stop it from rotating on the z axis and I need my ship to slow down when “left shift” is released rather than it suddenly stopping. This is my first attempt at using AddForce for a controller because my attempts with using Transform usually end up with the player hitting a static object and moving in a random direction afterwords.

Attach this script to an object with a RigidBody and turn off gravity:

var speed : float;
var yawspeed : float;
var pitchspeed : float;
function FixedUpdate(){
	if(Input.GetKeyDown(KeyCode.LeftShift))
    	rigidbody.AddForce(0,0,speed); 
	if(Input.GetKeyUp(KeyCode.LeftShift)) {
  		rigidbody.velocity = Vector3.zero;
    	rigidbody.angularVelocity = Vector3.zero; 
}
	transform.Rotate(0, Input.GetAxis("Horizontal")*yawspeed*Time.deltaTime, 0);
	transform.Rotate(Input.GetAxis("Vertical")*pitchspeed*Time.deltaTime, 0, 0);
}

I’m struggling with this one, so any help will be extremely appreciated! :smiley:

Apply the force along the forward vector of your transform:

rigidbody.Addforce(transform.forward * speed);

if You want your ship to move at a constant speed set its velocity rather than adding a force.

rigidbody.velocity = transform.forward * speed;

You can set the rotation using physics with rigigbody.MoveRotation:

Vector3 rotationVector = rigidbody.rotation;
rotationVector.x = Input.GetAxis("Vertical")*pitchspeed*Time.deltaTime;
rotationVector.y = Input.GetAxis("Horizontal")*yawspeed*Time.deltaTime;
rigidbody.MoveRotation(rotationVector);

To slow down when releasing shift you need to lerp the objects current velocity to zero, or a resting velocity. You can do this using Vector3.Lerp you could do this in update, but I find it more convenint to do stuff like this in a co-routine

public float decelerationTime = 1.0f;

Ienumerator Decelerate(){

	float t = 0;
	Vector3 fromVelocity = rigidbody.velocity;

	while(t < decelerationTime){
		rigidbody.velocity = Vector3.Lerp(fromVelocity, Vector3.zero, t);
		t += Time.deltaTime / decelerationTime;
		yield return null;
	}
} 

Then when you release shift start the Co-Routine:

 if(Input.GetKeyUp(KeyCode.LeftShift)) StartCoroutine(Decelerate());

you probably want to replace the Vector3.zero in the lerp method with something like

transform.forward * speed

so your ship doesn’t slow to a stop but rather goes back to its original speed.

But none of that code is tested :stuck_out_tongue: