This site uses strictly necessary cookies. More Information

X- Home /

# 2D plane physics, add torque based on direction

Hello,

Am trying to figure out how Retry game by Rovio works(watch this if you don't know the game : https://www.youtube.com/watch?v=z8hwVmLqAgg )

At first i thought it simply need to add positive torque when i press down and add negate torque when release, while making the plan move forward of course. unfortanately that gave me a very strange result, i kept trying and so far this is the best thing i came up with :

```
using UnityEngine;
using System.Collections;
public class PlanPhysics : MonoBehaviour
{
Rigidbody2D body;
Transform trans ;
public float flyPower;
private float flyPower_P;
public float rotatePowerUp, rotatePowerDown;
private float rotatePowerUp_P, rotatePowerDown_P;
public float rotateUpLimit, rotateDownLimit;
public float speed ;
private float speed_P;
public float maxSpeed;
Vector3 euler;
public float angular;
bool pressed;
// Use this for initialization
void Start ()
{
body = rigidbody2D;
trans = transform;
euler = trans.eulerAngles;
//
resetVariables ();
}
void resetVariables ()
{
rotatePowerUp_P = rotatePowerUp;
rotatePowerDown_P = rotatePowerDown;
flyPower_P = flyPower;
speed_P = speed;
}
void rotateDown ()
{
euler = trans.eulerAngles;
if (euler.z < 290) {
if (angular > -rotateDownLimit) {
rotatePowerDown_P += 200 * Time.deltaTime;
angular -= rotatePowerDown_P * Time.deltaTime;
}
body.angularVelocity = angular;
} else {
angular = 0;
body.angularVelocity = angular;
}
}
void rotateUp ()
{
euler = trans.eulerAngles;
if (angular < rotateUpLimit) {
if (angular < 0) {
rotatePowerUp_P += 300 * Time.deltaTime;
} else {
rotatePowerUp_P += 100 * Time.deltaTime;
}
angular += rotatePowerUp_P * Time.deltaTime;
}
body.angularVelocity = angular;
}
void flyUp ()
{
body.AddForce (new Vector2 (0, flyPower_P));
if (flyPower_P > 0) {
flyPower_P -= 10 * Time.deltaTime;
} else {
flyPower_P = 0;
}
}
void moveForward ()
{
speed_P += 100 * Time.deltaTime;
body.AddRelativeForce (Vector2.right * speed_P);
if (body.velocity.magnitude > maxSpeed) {
body.velocity = rigidbody2D.velocity.normalized * maxSpeed;
}
}
// Update is called once per frame
void Update ()
{
//
if (Input.GetKey (KeyCode.Space) || Input.GetMouseButton (0)) {
rotateUp ();
flyUp ();
moveForward ();
} else {
if (pressed) {
rotateDown ();
}
}
if (Input.GetKeyUp (KeyCode.Space) || Input.GetMouseButtonUp (0)) {
pressed = true;
resetVariables ();
}
}
void OnCollisionEnter2D (Collision2D coll)
{
angular = 0;
body.angularVelocity = angular;
pressed = false;
}
}
```

Now at the start it looks like it worked perfectly, but i found a "game kill" issue, say you kept pressing until the plane is leaning to the left vertically ( \ ) at certain point in a real plane if you leave everything and let physics do its job the plane should continue to rotate toward the left direction, but in my case it will go back to the right, this is expected because that's what i asked it to do by calling "rotateDown" when am not pressing anything, so what i need to know is how to figure out if i have to rotate the plane "down" with negative values (to the left) or with positive values (right).

I made this little .GIF to make everything clear :
https://dl.dropboxusercontent.com/u/88553415/fastGif/PlanPhsx.gif

(when the sky is dark it means am not pressing down)

Thank you very much and have a nice day.

**Answer** by Aladine
·
Oct 29, 2014 at 07:44 PM

Okay so i change the rotateDown() method to this and it gave me the result i needed however am still thinking that there is a better way to do it :

```
void rotateDown ()
{
euler = trans.eulerAngles;
if (euler.z > 120 && euler.z < 280) {
if (angular > -rotateDownLimit) {
rotatePowerDown_P += 200 * Time.deltaTime;
angular += rotatePowerDown_P * Time.deltaTime;
}
body.angularVelocity = angular;
} else if (euler.z > 280 && angular > 20) {
angular = 10;
} else if (euler.z < 120) {
if (angular > -rotateDownLimit) {
rotatePowerDown_P += 200 * Time.deltaTime;
angular -= rotatePowerDown_P * Time.deltaTime;
}
body.angularVelocity = angular;
}
}
```

Ins$$anonymous$$d of duplicating your angular rotation, you can probably simplify if to :

```
void rotateDown ()
{
euler = trans.eulerAngles;
if (euler.z > 280 && angular > 20) {
angular = 10;
} else if (euler.z < 280) {
if (angular > -rotateDownLimit) {
rotatePowerDown_P += 200 * Time.deltaTime;
// the parenthesis below should return either -1 or 1.
angular += (euler.z<120? -1:1) * rotatePowerDown_P * Time.deltaTime;
}
body.angularVelocity = angular;
}
}
```

Thanks but you just made the code shorter, that wasn't what i meant by a "better solution", till now my plane physics still doesn't feel like i wanted to, i will observe the game more and try to see what i need. thanks

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.