Search Unity

Top Down Space Ship Movement

Discussion in 'Physics' started by rbosse, May 30, 2015.

  1. rbosse

    rbosse

    Joined:
    May 21, 2015
    Posts:
    18
    Hey guys, I'm really starting to discouraged with this project. I'm attempting to make my top down shooter tilt and rotate in the angle it's turning, example in this vid:
    .

    I can get it to tilt but once I add any type of rotation, it starts freaking out and screws up the entire object. Below is what I have.


    Code (CSharp):
    1.     void FixedUpdate()
    2.     {
    3.         if (rb.velocity.magnitude > maxSpeed) // max speed set
    4.         {
    5.             rb.velocity = rb.velocity.normalized * maxSpeed;
    6.         }
    7.  
    8.         if (Input.GetKey(KeyCode.W))
    9.         {
    10.             rb.AddRelativeForce(new Vector3(0, 1, 0) * speed * Time.deltaTime);
    11.         }
    12.         if (Input.GetKey(KeyCode.S))
    13.         {
    14.             rb.AddRelativeForce(-new Vector3(0, 1, 0) * revSpeed * Time.deltaTime);
    15.         }
    16.         if (Input.GetKey(KeyCode.A))
    17.         {
    18.             transform.localRotation = Quaternion.Euler(0f, 1 * tilt, transform.localRotation.eulerAngles.z);
    19.         }
    20.         else
    21.         {
    22.             transform.localRotation = Quaternion.Euler(0f,Mathf.LerpAngle(transform.localRotation.eulerAngles.y, 0, Time.fixedDeltaTime * 15f), transform.localRotation.eulerAngles.z);
    23.         }
    24.  
    25.         if (Input.GetKey(KeyCode.D))
    26.         {
    27.             transform.localRotation = Quaternion.Euler(0f, -1 * tilt, transform.localRotation.eulerAngles.z);
    28.         }
    29.     }
    Can anyone help me with this? I've literally spent like 6 hours attempting every variation that I can think of to get this to work. Thank you ahead of time!!!

    FYI, I've added this in on line 18, but it ends up rotating and keeping one end of the plane up.
    Code (CSharp):
    1. (0f, transform.localRotation.eulerAngles.y + (rotationSpeed * leftAxis.x * Time.fixedDeltaTime), -leftAxis.x * tilt);
     
  2. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Don't get discouraged! Ever! What you need to do instead is close your computer gently (throw it at a wall) then take a light walk (punch the wall in rage for breaking your computer) and finally come back with a new perspective.

    Your problem right now is your code dealing with angles. Before you use anything in your code, you have to understand what it does.

    AddForce simply adds a force globally. This means that adding (0,0,1) will add 1 unit of force on the Z axis. What you want is transform.TransformDirection (0,0,1) which is basically (0,0,1) on the axis of the transform. So...

    Code (CSharp):
    1. float MoveSpeed = 5f;
    2. if (Input.GetKeyDown (KeyCode.S))
    3. {
    4.     rigidbody.AddForce (transform.InverseTransformDirection (Vector3.forward) * -MoveSpeed);
    5. }
    Quaternion.Euler simply takes the rotations we're used to using and makes it usable for the underlying math Unity does for orientations. An easy way to use Quaternion.Euler to rotate the object right is:

    Code (CSharp):
    1. float RotationSpeed = 5f;
    2. if (Input.GetKeydown (KeyCode.D))
    3. {
    4.     transform.rotation = Quaternion.Euler (0,transform.rotation.y + RotationSpeed, 0);
    5. }
    transform.localRotation applies a rotation relative to the object's parent. If the object has no parent (like in the video), this applies a global rotation. No reason why you would need this.
     
    Last edited: May 30, 2015
  3. rbosse

    rbosse

    Joined:
    May 21, 2015
    Posts:
    18
    I've attempted this and it isn't working the way I'd expect it to. It ends up facing straight up, I modified x/y/z of the Quaternion.Euler and it won't rotate left or right. Man, this is a lot more complicated than I thought. Going on 8 hours lol!
     
  4. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Import your models correctly. They're probably made for the XY plane if you got the default package. Alternatively, you could just set the x rotation (euler) to 90 degrees to flip the model onto the XY plane.

    By the way, don't think of the hours you've spent working. They mean nothing in game dev. Only results matter.
     
  5. rbosse

    rbosse

    Joined:
    May 21, 2015
    Posts:
    18
    Moving and rotation is easy. I want it to tilt on that rotation while it turns. I reset the model and also used a cube as an example it also doesn't tilt/rotate.

    Based on what I'm seeing, I need the parent to tilt and the child of that parent to rotate in a circle to end up keeping the inside wing lower so it doesn't twist incorrectly. That's what I'm having a problem with applying...
     
  6. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Hm... While creating that effect by directly modifying rotations might be convenient, it might be easier to use animations instead because dealing with rotations all over the place is just a pain.

    If you still want to directly modify rotations for the tilt effect, you need to define a variable so you don't overshoot and do barrel roles all the time.

    Code (CSharp):
    1.  
    2. float MaxTilt = 30f;
    3. float RotationSpeed = 5f;
    4. void Update ()
    5. {
    6.     if (Input.GetKeyDown (KeyCode.A))
    7.     {
    8.         float tilt = transform.rotation.z - RotationSpeed; //Tilting left
    9.         if (tilt < -MaxTilt) tilt = -Maxtilt; //Keeping the tilt within the bounds
    10.         transform.rotation = Quaternion.Euler (0, transform.rotation.y - RotationSpeed, tilt);
    11.     }
    12. }
    13.  
    There's no reason why it shouldn't work because these rotations are global but if it doesn't, take the easy way out and just use animations for the tilt effect. Animations will provide you more control over your effect anyways.
     
    Last edited: May 30, 2015
    rbosse likes this.
  7. rbosse

    rbosse

    Joined:
    May 21, 2015
    Posts:
    18
    Alright, I will give that a shot, thanks!
    FYI, http://badgamedeveloper.com/SilentDeath.html - I got it this far...

    Code (CSharp):
    1. transform.localRotation = Quaternion.Euler(0f, 1 * tilt, transform.localRotation.eulerAngles.z);
    2.             transform.parent.Rotate(0, 0, -1 * rotateSpeed * Time.deltaTime);
     
  8. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Consider losing the parent. It just muddles things up. If you do have a parent, you should be applying the tilt on the child and the Y rotation on the parent or you'll have the interesting results you're getting.
     
  9. rbosse

    rbosse

    Joined:
    May 21, 2015
    Posts:
    18
    Yeah I didn't wanna resort to animations but I will... thanks jpthek9!
     
  10. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    No problem! Just don't get discouraged and always remember why you're making games (passion, ambition, etc.).
     
    rbosse likes this.
  11. rbosse

    rbosse

    Joined:
    May 21, 2015
    Posts:
    18
    Yeah I'm just gonna go to bed. I've spent entirely too much time on such a simple task that can be done easier...
     
  12. Cnc96

    Cnc96

    Joined:
    Dec 17, 2013
    Posts:
    57
    Hi,
    I had a WipeOut styled game where I had an object bank as the ship turned. I'll post the code that I used here, and hopefully it'll be useful :) I've added comments to the code so you know what everything does
    Code (CSharp):
    1. //Creating a new Vector3 to store the rotation
    2. Vector3 newRot = transform.eulerAngles;
    3.  
    4. //Assigning the new rotation. Change the '.z' after newRot to which ever axis you want the ship to rotate around. steerAxis is a variable that holds the input from the player, and maxRotation is the obviously the max angle you want the object to rotate to. turnSpeed and rotVelocity are values relating to how fast you want the object to rotate to and could most likely be the same thing.
    5. newRot.z = Mathf.SmoothDampAngle (newRot.z, steerAxis * - maxRotation * GetComponent<Rigidbody>().angularDrag, ref turnSpeed, rotVelocity);
    6.  
    7. //This assigns the new rotation to the object          
    8. transform.eulerAngles = newRot;