Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice

Question Smooth speed

Discussion in 'Physics' started by MatheusMarkies, Jan 25, 2021.

  1. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    I am developing a script for an airplane.
    However now I have a problem with changing the speed. She is changing values very fast so the plane is stuck in the air.


    Speed change:
    Code (CSharp):
    1.  
    2.         if (Input.GetKey(KeyCode.Space))
    3.         Energy = (Energy + motorEnergy) - 5 * airDensity * rb.mass * Time.deltaTime;
    4.         rb.AddForce((Energy) * VectorDir);
    5.  
    6.         rb.velocity = Mathf.SmoothStep(oldVelocity,rb.velocity.magnitude, Mathf.Clamp01(rb.velocity.magnitude)/oldVelocity) * VectorDir;
    7.  
    8.         if (Energy > 0)
    9.         Energy = Mathf.SmoothStep(Energy, 0, Mathf.Sqrt(rb.mass * 10 * airDensity / rb.drag * Time.deltaTime * Time.deltaTime));
    10.  
    11.         if (Energy < 0)
    12.             Energy = 0;
    13.  
    Script:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FlyController : MonoBehaviour
    6. {
    7.  
    8.     public float LiftCoefficient = 0.009f;
    9.     public float DragCoefficient = 0.001f;
    10.     public float BrakeCoefficient = 0.09f;
    11.     public float motorEnergy = 350f;
    12.     Rigidbody rb;
    13.     public float Energy = 0;
    14.     public float airDensity = 2f;
    15.  
    16.     public float FlareCoefficient = 0.01f;
    17.  
    18.     float breakAngle;
    19.     float angularDrag;
    20.     float drag;
    21.     float rolling;
    22.     float pitch;
    23.     float yaw;
    24.     float oldDrag;
    25.     float oldAngularDrag;
    26.     float oldVelocity;
    27.  
    28.     public float AerodynamicEffect = 0.2f;
    29.     public float ControlsMultiplier = 1f;
    30.     public float AerodynamicYawMultiplier = 3f;
    31.     void Start()
    32.     {
    33.         rb = GetComponent<Rigidbody>();
    34.         angularDrag = rb.angularDrag;
    35.         drag = rb.drag;
    36.     }
    37.     void Update()
    38.     {
    39.  
    40.         Vector3 LiftDir = transform.rotation * Vector3.up;
    41.         Vector3 VectorDir = transform.rotation * Vector3.forward;
    42.         Vector3 DragDir = transform.rotation * Vector3.back;
    43.  
    44.         if (Input.GetKey(KeyCode.Space))
    45.         Energy = (Energy + motorEnergy) - 5 * airDensity * rb.mass * Time.deltaTime;
    46.         rb.AddForce((Energy) * VectorDir);
    47.  
    48.         rb.velocity = Mathf.SmoothStep(oldVelocity,rb.velocity.magnitude, Mathf.Clamp01(rb.velocity.magnitude)/oldVelocity) * VectorDir;
    49.  
    50.         if (Energy > 0)
    51.         Energy = Mathf.SmoothStep(Energy, 0, Mathf.Sqrt(rb.mass * 10 * airDensity / rb.drag * Time.deltaTime * Time.deltaTime));
    52.  
    53.         if (Energy < 0)
    54.             Energy = 0;
    55.  
    56.        // rb.AddForce(acceleration * VectorDir * Time.deltaTime,ForceMode.Impulse);
    57.         //rb.velocity = acceleration * VectorDir;
    58.         rb.AddForce(LiftForce(LiftCoefficient, this.airDensity, rb.velocity.magnitude) * LiftDir * (0.1f+Mathf.Sqrt(1-Vector3.Dot(Vector3.forward, VectorDir) * Vector3.Dot(Vector3.forward, VectorDir))));
    59.  
    60.         if (Input.GetKey(KeyCode.LeftShift))
    61.         {
    62.             if (breakAngle < 90)
    63.                 breakAngle = breakAngle + Mathf.Lerp(0.6f, 0, breakAngle / 90);
    64.         }
    65.         else
    66.             if (breakAngle > 0)
    67.             breakAngle = breakAngle + Mathf.Lerp(-2f, 0, breakAngle / 90);
    68.         else
    69.             breakAngle = 0;
    70.        
    71.         rb.drag = Mathf.SmoothStep(oldDrag,(DragForce(DragCoefficient, this.airDensity, rb.velocity.magnitude) * DragDir).magnitude, Mathf.Clamp01(DragForce(DragCoefficient, this.airDensity, rb.velocity.magnitude))/ oldDrag);
    72.         rb.angularDrag = Mathf.SmoothStep(oldAngularDrag, angularDrag * rb.velocity.magnitude * VectorDir.magnitude * this.airDensity, Mathf.Clamp01(angularDrag * rb.velocity.magnitude * VectorDir.magnitude * this.airDensity) / oldAngularDrag);
    73.         Aerodynamic();
    74.     }
    75.     void LateUpdate()
    76.     {
    77.         oldDrag = rb.drag;
    78.         oldAngularDrag = rb.angularDrag;
    79.         oldVelocity = rb.velocity.magnitude;
    80.     }
    81.  
    82.     float LiftForce(float liftC, float AirDensity, float Speed, float WingSurface = 1)
    83.     {
    84.         float lift = liftC * AirDensity * Speed * Speed * WingSurface / 2;
    85.         return lift;
    86.     }
    87.     float DragForce(float dragC, float AirDensity, float Speed, float WingSurface = 1)
    88.     {
    89.         float drag = this.drag + (dragC * AirDensity * Speed * Speed * WingSurface / 2);
    90.         return drag + BrakeForce(BrakeCoefficient, this.airDensity, Speed) * Mathf.Sin(breakAngle);
    91.     }
    92.     float BrakeForce(float breakC, float AirDensity, float Speed, float WingSurface = 1)
    93.     {
    94.         float Break = breakC * AirDensity * Speed * Speed * WingSurface / 2;
    95.         return Break;
    96.     }
    97.     void Aerodynamic()
    98.     {
    99.  
    100.         if (Input.GetKey(KeyCode.A))
    101.         {
    102.             if (yaw > 0)
    103.                 yaw = 0;
    104.             rolling += 0.05f;
    105.             yaw -= 0.1f;
    106.         }
    107.         else
    108.         if (Input.GetKey(KeyCode.D))
    109.         {
    110.             if (yaw < 0)
    111.                 yaw = 0;
    112.             rolling -= 0.05f;
    113.             yaw += 0.1f;
    114.         }
    115.         else
    116.             rolling = 0;
    117.  
    118.         if (Input.GetKey(KeyCode.W))
    119.             pitch += 0.05f;
    120.         else
    121.         if (Input.GetKey(KeyCode.S))
    122.             pitch -= 0.05f;
    123.         else
    124.             pitch = 0;
    125.  
    126.         Vector3 torque = Vector3.zero;
    127.  
    128.         torque += Mathf.Lerp(yaw* AerodynamicYawMultiplier, 0, Mathf.Abs(Mathf.Cos(transform.localRotation.z*2))) * transform.up;
    129.         torque += pitch * ControlsMultiplier * transform.right;
    130.         torque += rolling * ControlsMultiplier * transform.forward;
    131.  
    132.         torque -= transform.right * rb.velocity.magnitude * FlareCoefficient * airDensity;
    133.        
    134.         rb.AddTorque(torque * airDensity * rb.velocity.magnitude);
    135.  
    136.     }
    137.  
    138. }
    139.  
     
  2. captainspaceman

    captainspaceman

    Joined:
    Jul 14, 2017
    Posts:
    42
    Why not just use addForce with a slerp counter? It would be perfectly smooth. You can just set the mass and drag of the rigidbody in the inspector. I would use addForceAtPosition where the engine is to make it more realistic, though you'd need to make sure it is centered perfectly for that.

    Just keep a floating-point counter that increments when the player wants to accelerate and multiply the force by (that counter / the max value of that counter). Then when the player steps off the gas, decrement the counter. You could even keep a second counter that decrements and increments faster to slerp the slerp. Though I think this is entirely unnecessary as addForce already kind of realistically does that for you. The acceleration you get from addForce is relative to the object's current momentum, mass, and drag, so I don't think you need to keep track of previous velocities and try interpolating between them, seems overly complicated but maybe I don't really understand it.
     
    MatheusMarkies likes this.