1. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice
  2. We're looking for feedback on Unity Starter Kits! Let us know what you’d like.
    Dismiss Notice
  3. We’re giving 2017.1 beta testers a chance to win t-shirts and a Nintendo Switch. Read more on the blog.
    Dismiss Notice
  4. We want to know how you learned Unity! Help us by taking this quick survey and have a chance at a $25 gift card
    Dismiss Notice
  5. Unity 5.6 is now released.
    Dismiss Notice
  6. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice

Control a 2D Helicopter

Discussion in '2D' started by Andre1985, Jun 17, 2017.

  1. Andre1985

    Andre1985

    Joined:
    Jun 17, 2017
    Posts:
    4
    Hello,
    i'm new in unity and try to create my first game. For the first game i need a 2D helicopter.

    But i have the problem to script the right controls and physics.

    I will need a movemenet similiar to this one: https://gamemechanicexplorer.com/#thrust-4

    But i have a problem to convert it to unity.

    Especially with this code:

    Code (JavaScript):
    1.    this.ship.body.acceleration.x = Math.cos(this.ship.rotation) * this.ACCELERATION;
    2.        this.ship.body.acceleration.y = Math.sin(this.ship.rotation) * this.ACCELERATION;

    My Code in Unity:
    Code (CSharp):
    1.  
    2.   transform.position = new Vector3(Mathf.Cos(transform.rotation.z) * 10, Mathf.Sin(transform.rotation.z) * 10, 0);
    But my Object change only the Position for one time.

    How can i move an object by the rotation angle?

    Please help some total beginner :) Thank you
     
    Last edited: Jun 18, 2017
  2. Andre1985

    Andre1985

    Joined:
    Jun 17, 2017
    Posts:
    4
    Here is another example of the movement.



    Can some give an example how i can realize an similiar movement?
     
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    5,241
    Computers are very literal! They will do exactly what you tell them.

    In this case, you are telling the object to set its position to some point on a circle (around the origin, i.e. 0,0,0) that depends on its rotation. So that's what it does.

    It's not moving because you haven't told it to move; you've just told it to stay at some point on a circle.

    To do movement like what you describe, you're going to need a lot more than this. Probably you need a property on your script to keep track of the helicopter's velocity. Call this "Vector2 velocity". So then you'll compute an acceleration based on the inputs (or maybe the current rotation), as in the JavaScript code you're translating, and do velocity += acceleration * Time.deltaTime to update your velocity. And then do transform.position += velocity * Time.deltaTime to update your position.

    If all this sounds hard, you probably need to go back and do more of the tutorials. Which ones have you done already? Maybe we can help you better if we understand how much you probably already know.
     
    Andre1985 likes this.
  4. Andre1985

    Andre1985

    Joined:
    Jun 17, 2017
    Posts:
    4
    Thanks for your help! :)

    I have tried a little bit and now i have some similiar Movement.

    Here some example:
    [​IMG]


    And this is the actual code for the Helicopter:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Heli : MonoBehaviour
    6. {
    7.     public float turnpower = 0.2f;
    8.     public float thrust = 500f;
    9.     float velocity_x = 0;
    10.     bool landed = false;
    11.     Rigidbody2D rb;
    12.     GameObject trig;
    13.     public PolygonCollider2D test;
    14.     void Start()
    15.     {
    16.         rb = GetComponent<Rigidbody2D>();
    17.         test = GetComponent<PolygonCollider2D>();
    18.  
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void FixedUpdate()
    23.     {
    24.         float x = Mathf.Cos(rb.rotation) * 0.1f;
    25.         float y = Mathf.Sin(rb.rotation);
    26.  
    27.         if (Input.GetKey(KeyCode.UpArrow))
    28.         {
    29.  
    30.             landed = false;
    31.             rb.AddForce(Vector3.up * Time.deltaTime * thrust);
    32.         }
    33.  
    34.         if (Input.GetKey(KeyCode.LeftArrow))
    35.         {
    36.             if (velocity_x < 10 && !landed)
    37.             {
    38.                 velocity_x += 0.2f;
    39.                 transform.Rotate(new Vector3(0, 0, turnpower));
    40.             }
    41.  
    42.         }
    43.  
    44.  
    45.         if (Input.GetKey(KeyCode.RightArrow))
    46.         {
    47.             if (velocity_x > -10 && !landed)
    48.             {
    49.                 velocity_x -= 0.2f;
    50.             }
    51.             transform.Rotate(new Vector3(0, 0, turnpower));
    52.         }
    53.  
    54.  
    55.         rb.velocity = new Vector2(-velocity_x, rb.velocity.y);
    56.     }
    57.  
    58.  
    59.     void OnTriggerEnter2D(Collider2D test)
    60.     {
    61.         landed = true;
    62.         Debug.Log("Brake");
    63.         velocity_x = 0;
    64.     }
    65.  
    66. }
    67.  
    68.  
    It's not perfect at the moment but it works for me.
     
    JoeStrout and jeffreyschoch like this.
  5. Andre1985

    Andre1985

    Joined:
    Jun 17, 2017
    Posts:
    4
    Shame on me for the first code. I think i have optimized my code a little bit o_O

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Heli : MonoBehaviour
    6. {
    7.     bool landed = false;
    8.     Rigidbody2D rb;
    9.     void Start()
    10.     {
    11.         rb = GetComponent<Rigidbody2D>();
    12.  
    13.     }
    14.  
    15.     // Update is called once per frame
    16.     void Update()
    17.     {
    18.  
    19.         if (Input.GetKey(KeyCode.UpArrow))
    20.         {
    21.  
    22.             rb.AddForce(transform.up * 500 * Time.deltaTime);
    23.            
    24.         }
    25.  
    26.         if (Input.GetKey(KeyCode.LeftArrow))
    27.         {
    28.             transform.Rotate(Vector3.forward * 50 * Time.deltaTime);
    29.  
    30.         }
    31.  
    32.  
    33.         if (Input.GetKey(KeyCode.RightArrow))
    34.         {
    35.             transform.Rotate(Vector3.back * 50 * Time.deltaTime);
    36.         }
    37.  
    38.  
    39.  
    40.     }
    41. }
    42.  
    43.  
     
  6. jeffreyschoch

    jeffreyschoch

    Joined:
    Jan 21, 2015
    Posts:
    1,657
    You'll want to get your inputs in Update every frame (perhaps storing the value in a variable), and then apply your forces in FixedUpdate as that is in sync with the physics timestep. Time.deltaTime will still work in FixedUpdate.