Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Control a 2D Helicopter

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

  1. Andre1985

    Andre1985

    Joined:
    Jun 17, 2017
    Posts:
    5
    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:
    5
    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:
    9,859
    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:
    5
    Thanks for your help! :)

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

    Here some example:



    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 LiterallyJeff like this.
  5. Andre1985

    Andre1985

    Joined:
    Jun 17, 2017
    Posts:
    5
    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. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,807
    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.