SpaceShip script help

Okay, my goal is to create a spaceship that moves depending on the speed.
The speed can be increased or decreased by the up / down buttons.

However, I want to include the left and right also, so that the ship can turn, I played with the script with floats vectors euler etc etc, I couldn’t come up with a solution , so I just cleaned up my script and left it at this so someone can help me sort it out. At the moment the ship will continue going + in the Z axis , but I want to make a smooth control of the spaceship, the turns and for the ship to keep going at its speed, help will be appreciated.

var speed: float = 0;
var rotateR = 10;
var rotateL = -10;
var turnSpeed = 20;




function Update () {
transform.renderer.material.color = Color.yellow;

//	var translation : float = Input.GetAxis ("Vertical") * speed;
 //   var arotation : float = Input.GetAxis ("Horizontal") * speed;
	
//	arotation *= Time.deltaTime;
//    translation *= Time.deltaTime;
	
  transform.position.z += speed * Time.deltaTime;
var rotX = transform.eulerAngles.y;

if (rotX >= 1) { transform.position.x += speed * Time.deltaTime; }
if (rotX >= 181) { transform.position.x -= speed * Time.deltaTime; } 
if (speed >= 35) speed = 35;


if (Input.GetKey ("up")) { speed = speed + 0.02; }



 if (Input.GetKey("left")) {

	transform.Rotate(0, rotateL * Time.deltaTime * speed, 0);
//	  transform.position.x -= turnSpeed * Time.deltaTime;
	}

if (Input.GetKey("right")) {

	transform.Rotate(0, rotateR * Time.deltaTime * speed, 0);
//	  transform.position.x += turnSpeed * Time.deltaTime;
	}
if (Input.GetKey ("down")) { speed = speed - 0.09; }

}

For your problem:

Your forward speed should technically work. You’re increasing it while you press Up, and decreasing it while you press Down. However, transform.position references it’s global position, so instead you should use transform.localPosition.z. This way, it moves forward on it’s local axes rather than by the world coordinates.

To make your ship rotate smoothly, I would recommend a similar approach to what you’re doing with speed. Set up a variable like “currentRotate”, and apply this via transform.Rotate() every frame. Then, make the Right and Left keys add or subtract to this variable by a given amount. Then each frame make sure you subtract or add (depending on whether it’s positive or negative) from this variable.

Using Subtract can give a pretty static feel, though, and it can also make it a little more confusing as you’ll be using cases for positive and negative. I like to use Multiply in cases like these, where if the rotate variable is not equal to 0 you multiply the rotate variable by something like .9. This makes your rotation into a curve, rather than a line, and is a lot smoother. If you do this, you’ll want to clamp your values on both the maximums. and the minimums. So, if the Absolute value (Mathf.Abs) of your rotate value is less than .1, just clamp it to 0. Otherwise, because you’re multiplying it by a decimal it will technically never reach 0. Then, you’ll also want to make sure you can’t rotate more than, say, 20 degrees per frame, otherwise it would be pretty tough to control.

I hope that helps with your problem.

If you don’t mind me critiquing your code a bit, I have a few things which may make your code more concise.

  • Instead of having RotateL and RotateR be the same numbers except negatives, you could simply combine these into one variable and multiply it by -1 when you call the Rotate() function.

  • Currently you’re turning your ship yellow every single frame. While you probably won’t notice the difference, this is a pretty unnecessary command! Instead of sticking that command in the Update() function, you could create a new function called Start(), which is called when the object is created.

  • You seem to be access your renderer through transform, which is kind of unnecessary. Saying transform.renderer.material is exactly the same as saying renderer.material, except with more letters! I’ll bet this is all cut out anyways when the code is compiled, but it might make it more organized if you were to cut out the transform. part.

  • Rather than using the Input.GetKey() function, it would make your motions more fluid if you used the Input.GetAxis() function. The GetAxis function will return a float which gradually increases to 1 as you press the key. If you multiply the GetAxis variable against your calculations, it will make it all appear much smoother.

  • When you are multiplying numbers together which have decimals, it’s generally important to declare them as the correct variable types. I’m pretty sure your rotate variables are declared as integers right now because you’re not defaulting them to numbers with decimals, which means you can’t add decimals to them in the Inspector. Instead, do var Rotate:float to ensure that they’re declared correctly.

I hope I’ve been of help. Happy coding!

Thanks for the explanation, now only if I can do all of that :wink:

I’ll give it a shot, you did explain it very throughly and thanks for that, but however a script example might’have helped a bit more :slight_smile:

I’d rather teach you to write your own code than to write it for you :slight_smile:

If you do run into problems with my explanation, though, I’d be happy to give you some sample code.

okay lets work on this together, here’s what i did so far :slight_smile:

var speed: float = 0;
var currentRotate: float = 0;



function Update () {
transform.renderer.material.color = Color.yellow;

	
  transform.localPosition.z += speed * Time.deltaTime;
  transform.Rotate(Vector3.up * speed * Time.deltaTime);
  
var rotX = transform.eulerAngles.y;

if (rotX >= 1) { transform.position.x += speed * Time.deltaTime; }
if (rotX >= 181) { transform.position.x -= speed * Time.deltaTime; } 
if (speed >= 35) speed = 35;


if (Input.GetKey ("up")) { speed = speed + 0.02; }



 if (Input.GetKey("left")) {

		currentRotate--;
	}

if (Input.GetKey("right")) {

		currentRotate++;
}
if (Input.GetKey ("down")) { speed = speed - 0.09; }

}

i could use sample code of the get axis part, and an explanation so i can learn it, and the rest i’m not sure how to include to make it rotate, so i need help there :slight_smile:

For the GetAxis part, you simply do:

Input.GetAxis(“Horizontal”);

This will return a float between -1.0 and 1.0, depending on whether you’re pressing left or right.

If you multiply this inside your rotate that you’ve just posted, I believe you won’t even need the Input.GetKey() functions towards the bottom.

The way you have it setup, multiplying your rotate by speed, you will rotate faster if you are moving forward faster. This is different from what I posted earlier, but you could simply use a static rotateSpeed variable to modify that. Your GetAxis variable will control the smoothness of it… you can modify how quickly it approaches 1 or -1 in your Input settings with a variable called Gravity. The lower it is, the smoother it will be.

in function Update () {

transform.localPosition.z += speed * Time.deltaTime;

var test : float = Input.GetAxis (“Horizontal”);

if (test > 0) { transform.Rotate(Vector3.up * speed * Time.deltaTime); }
else if (test < 0 ) { transform.Rotate(Vector3.up * speed * Time.deltaTime); }

does this seem right ???

and thanks for the info, i’m not worying much bout the speed as of now, I will edit that later on, first I need to fix this mess :slight_smile:

and i’m not using gravity because they’re flying, or are u referring to something else?

Actually it’s much easier!

Instead of those if statements, you can simply say:

transform.Rotate(Vector3.up * speed * Time.deltaTime * test);

When test is negative, multiplying it against your rotation will flip it in the other direction. That should achieve the desired effect

EDIT: Also, if you aren’t pressing a Key the GetAxis() will return 0, so your rotation will be nullified

Haha, yeah that was dumb of me, ,

ok, so here’s what we have so far:

var speed: float = 0;

function Update () {

transform.localPosition.z += speed * Time.deltaTime;

var test : float = Input.GetAxis (“Horizontal”);

transform.Rotate(Vector3.up * speed * Time.deltaTime * test);

if (Input.GetKey (“up”)) { speed = speed + 0.02; }

}

so in order to fix it so its not only towards the Z axes, i have to add this?

if (rotX >= 1) { transform.position.x += speed * Time.deltaTime; }
if (rotX >= 181) { transform.position.x -= speed * Time.deltaTime; }

however, all of this and the object will still continue to move to the +z axes,

if the object turns to a 180 the z axes shold be lowering instead

edit: this is what i did so far, and i’m failing :slight_smile:

var speed: float = 0;
var currentRotate: float = 0;



function Update () {
transform.renderer.material.color = Color.yellow;

	
  transform.localPosition.z += speed * Time.deltaTime;

     var test : float = Input.GetAxis ("Horizontal");
  
transform.Rotate(Vector3.up * speed * Time.deltaTime * test);

  
var rotX = transform.eulerAngles.y;



if (rotX >= 1) { transform.position.x += speed * Time.deltaTime; }
if (rotX >= 90) { transform.localPosition.z += speed * Time.deltaTime * -2; }
 if (rotX >= 181) { transform.position.x -= speed * Time.deltaTime;    transform.localPosition.z += speed * Time.deltaTime; } 
 
if (speed >= 35) speed = 35;


if (Input.GetKey ("up")) { speed = speed + 0.02; }


}

No, it should actually work if you’re using localPosition.z

Modifying that variable will move it along the axis that your rotation values have it facing. So if you’ve rotated your ship, and you modify the localPosition.z, it will move in the direction that you’ve rotated it (assuming that you’ve built your ship facing the z axis)

if i only leave this:

var speed: float = 0;

function Update () {
transform.renderer.material.color = Color.yellow;

	
  transform.localPosition.z += speed * Time.deltaTime;

     var test : float = Input.GetAxis ("Horizontal");
  
	transform.Rotate(Vector3.up * speed * Time.deltaTime * test);

   
if (speed >= 35) speed = 35;


if (Input.GetKey ("up")) { speed = speed + 0.02; }

}

it isn’t working, well the ship rotates and moves to the Z axis, but only z, the X stays the same

I’m not sure I understand. The code works fine in my Unity, unless you’re trying to do something I’m not aware of.

How do you want the X to change?

Well since I’m pressing Left, the “box” (ship) rotates towards the left, but I also want it to turn towards the left, not just rotate, and it keeps driving towards the Z axis,

so if the ship were to turn, the X axis would change as well,
do you get what i’m trying to say?

edit: also if it turns to a 180 degrees, the Z axis should go in minus, ?

you know if you just want your ship to have some physics like drag, and to keep sliding while turning why not make it a rigid body? you could use rigidbody.AddForce to move forward and back and rigidbody.AddTorque to turn and make sure you deselect gravity on the rigidbody options. depending on the axid that you are using.