Advertisement
Guest User

AeroplaneController.cs

a guest
Apr 7th, 2020
375
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.40 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4.  
  5. namespace UnityStandardAssets.Vehicles.Aeroplane
  6. {
  7.     [RequireComponent(typeof (Rigidbody))]
  8.     public class AeroplaneController : MonoBehaviour
  9.     {
  10.         public float m_MaxEnginePower = 40f;        // The maximum output of the engine.
  11.         [SerializeField] private float m_Lift = 0.002f;               // The amount of lift generated by the aeroplane moving forwards.
  12.         [SerializeField] private float m_ZeroLiftSpeed = 300;         // The speed at which lift is no longer applied.
  13.         [SerializeField] private float m_RollEffect = 1f;             // The strength of effect for roll input.
  14.         [SerializeField] private float m_PitchEffect = 1f;            // The strength of effect for pitch input.
  15.         [SerializeField] private float m_YawEffect = 0.2f;            // The strength of effect for yaw input.
  16.         [SerializeField] private float m_BankedTurnEffect = 0.5f;     // The amount of turn from doing a banked turn.
  17.         [SerializeField] private float m_AerodynamicEffect = 0.02f;   // How much aerodynamics affect the speed of the aeroplane.
  18.         [SerializeField] private float m_AutoTurnPitch = 0.5f;        // How much the aeroplane automatically pitches when in a banked turn.
  19.         [SerializeField] private float m_AutoRollLevel = 0.2f;        // How much the aeroplane tries to level when not rolling.
  20.         [SerializeField] private float m_AutoPitchLevel = 0.2f;       // How much the aeroplane tries to level when not pitching.
  21.         [SerializeField] private float m_AirBrakesEffect = 3f;        // How much the air brakes effect the drag.
  22.         [SerializeField] private float m_ThrottleChangeSpeed = 0.3f;  // The speed with which the throttle changes.
  23.         [SerializeField] private float m_DragIncreaseFactor = 0.001f; // how much drag should increase with speed.
  24.  
  25.         public float Altitude { get; private set; }                     // The aeroplane's height above the ground.
  26.         public float Throttle { get; private set; }                     // The amount of throttle being used.
  27.         public bool AirBrakes { get; private set; }                     // Whether or not the air brakes are being applied.
  28.         public float ForwardSpeed { get; private set; }                 // How fast the aeroplane is traveling in it's forward direction.
  29.         public float EnginePower { get; private set; }                  // How much power the engine is being given.
  30.         public float MaxEnginePower{ get { return m_MaxEnginePower; }}    // The maximum output of the engine.
  31.         public float RollAngle { get; private set; }
  32.         public float PitchAngle { get; private set; }
  33.         public float RollInput { get; private set; }
  34.         public float PitchInput { get; private set; }
  35.         public float YawInput { get; private set; }
  36.         public float ThrottleInput { get; private set; }
  37.  
  38.         private float m_OriginalDrag;         // The drag when the scene starts.
  39.         private float m_OriginalAngularDrag;  // The angular drag when the scene starts.
  40.         private float m_AeroFactor;
  41.         private bool m_Immobilized = false;   // used for making the plane uncontrollable, i.e. if it has been hit or crashed.
  42.         private float m_BankedTurnAmount;
  43.         private Rigidbody m_Rigidbody;
  44.         WheelCollider[] m_WheelColliders;
  45.  
  46.         public Rigidbody rb;
  47.         public GameObject SpeedDial;
  48.        
  49.  
  50.         private void Start()
  51.         {  
  52.             m_Rigidbody = GetComponent<Rigidbody>();
  53.             // Store original drag settings, these are modified during flight.
  54.             m_OriginalDrag = m_Rigidbody.drag;
  55.             m_OriginalAngularDrag = m_Rigidbody.angularDrag;
  56.  
  57.             for (int i = 0; i < transform.childCount; i++ )
  58.             {
  59.                 foreach (var componentsInChild in transform.GetChild(i).GetComponentsInChildren<WheelCollider>())
  60.                 {
  61.                     componentsInChild.motorTorque = 0.18f;
  62.                 }
  63.             }
  64.            
  65.         }
  66.  
  67.        
  68.  
  69.  
  70.         public void Move(float rollInput, float pitchInput, float yawInput, float throttleInput, bool airBrakes)
  71.         {
  72.             // transfer input parameters into properties.s
  73.             RollInput = rollInput;
  74.             PitchInput = pitchInput;
  75.             YawInput = yawInput;
  76.             ThrottleInput = throttleInput;
  77.             AirBrakes = airBrakes;
  78.  
  79.             ClampInputs();
  80.  
  81.             CalculateRollAndPitchAngles();
  82.  
  83.             AutoLevel();
  84.  
  85.             CalculateForwardSpeed();
  86.  
  87.             ControlThrottle();
  88.  
  89.             CalculateDrag();
  90.  
  91.             CaluclateAerodynamicEffect();
  92.  
  93.             CalculateLinearForces();
  94.  
  95.             CalculateTorque();
  96.  
  97.             CalculateAltitude();
  98.         }
  99.  
  100.  
  101.         private void ClampInputs()
  102.         {
  103.             // clamp the inputs to -1 to 1 range
  104.             RollInput = Mathf.Clamp(RollInput, -1, 1);
  105.             PitchInput = Mathf.Clamp(PitchInput, -1, 1);
  106.             YawInput = Mathf.Clamp(YawInput, -1, 1);
  107.             ThrottleInput = Mathf.Clamp(ThrottleInput, -1, 1);
  108.         }
  109.  
  110.  
  111.         private void CalculateRollAndPitchAngles()
  112.         {
  113.             // Calculate roll & pitch angles
  114.             // Calculate the flat forward direction (with no y component).
  115.             var flatForward = transform.forward;
  116.             flatForward.y = 0;
  117.             // If the flat forward vector is non-zero (which would only happen if the plane was pointing exactly straight upwards)
  118.             if (flatForward.sqrMagnitude > 0)
  119.             {
  120.                 flatForward.Normalize();
  121.                 // calculate current pitch angle
  122.                 var localFlatForward = transform.InverseTransformDirection(flatForward);
  123.                 PitchAngle = Mathf.Atan2(localFlatForward.y, localFlatForward.z);
  124.                 // calculate current roll angle
  125.                 var flatRight = Vector3.Cross(Vector3.up, flatForward);
  126.                 var localFlatRight = transform.InverseTransformDirection(flatRight);
  127.                 RollAngle = Mathf.Atan2(localFlatRight.y, localFlatRight.x);
  128.             }
  129.         }
  130.  
  131.  
  132.         private void AutoLevel()
  133.         {
  134.             // The banked turn amount (between -1 and 1) is the sine of the roll angle.
  135.             // this is an amount applied to elevator input if the user is only using the banking controls,
  136.             // because that's what people expect to happen in games!
  137.             m_BankedTurnAmount = Mathf.Sin(RollAngle);
  138.             // auto level roll, if there's no roll input:
  139.             if (RollInput == 0f)
  140.             {
  141.                 RollInput = -RollAngle*m_AutoRollLevel;
  142.             }
  143.             // auto correct pitch, if no pitch input (but also apply the banked turn amount)
  144.             if (PitchInput == 0f)
  145.             {
  146.                 PitchInput = -PitchAngle*m_AutoPitchLevel;
  147.                 PitchInput -= Mathf.Abs(m_BankedTurnAmount*m_BankedTurnAmount*m_AutoTurnPitch);
  148.             }
  149.         }
  150.  
  151.  
  152.         private void CalculateForwardSpeed()
  153.         {
  154.             // Forward speed is the speed in the planes's forward direction (not the same as its velocity, eg if falling in a stall)
  155.             var localVelocity = transform.InverseTransformDirection(m_Rigidbody.velocity);
  156.             ForwardSpeed = Mathf.Max(0, localVelocity.z);
  157.         }
  158.  
  159.  
  160.         private void ControlThrottle()
  161.         {
  162.             // override throttle if immobilized
  163.             if (m_Immobilized)
  164.             {
  165.                 ThrottleInput = -0.5f;
  166.             }
  167.  
  168.             // Adjust throttle based on throttle input (or immobilized state)
  169.             Throttle = Mathf.Clamp01(Throttle + ThrottleInput*Time.deltaTime*m_ThrottleChangeSpeed);
  170.  
  171.             // current engine power is just:
  172.             EnginePower = Throttle*m_MaxEnginePower;
  173.         }
  174.  
  175.  
  176.         private void CalculateDrag()
  177.         {
  178.             // increase the drag based on speed, since a constant drag doesn't seem "Real" (tm) enough
  179.             float extraDrag = m_Rigidbody.velocity.magnitude*m_DragIncreaseFactor;
  180.             // Air brakes work by directly modifying drag. This part is actually pretty realistic!
  181.             m_Rigidbody.drag = (AirBrakes ? (m_OriginalDrag + extraDrag)*m_AirBrakesEffect : m_OriginalDrag + extraDrag);
  182.             // Forward speed affects angular drag - at high forward speed, it's much harder for the plane to spin
  183.             m_Rigidbody.angularDrag = m_OriginalAngularDrag*ForwardSpeed;
  184.         }
  185.  
  186.  
  187.         private void CaluclateAerodynamicEffect()
  188.         {
  189.             // "Aerodynamic" calculations. This is a very simple approximation of the effect that a plane
  190.             // will naturally try to align itself in the direction that it's facing when moving at speed.
  191.             // Without this, the plane would behave a bit like the asteroids spaceship!
  192.             if (m_Rigidbody.velocity.magnitude > 0)
  193.             {
  194.                 // compare the direction we're pointing with the direction we're moving:
  195.                 m_AeroFactor = Vector3.Dot(transform.forward, m_Rigidbody.velocity.normalized);
  196.                 // multipled by itself results in a desirable rolloff curve of the effect
  197.                 m_AeroFactor *= m_AeroFactor;
  198.                 // Finally we calculate a new velocity by bending the current velocity direction towards
  199.                 // the the direction the plane is facing, by an amount based on this aeroFactor
  200.                 var newVelocity = Vector3.Lerp(m_Rigidbody.velocity, transform.forward*ForwardSpeed,
  201.                                                m_AeroFactor*ForwardSpeed*m_AerodynamicEffect*Time.deltaTime);
  202.                 m_Rigidbody.velocity = newVelocity;
  203.  
  204.                 // also rotate the plane towards the direction of movement - this should be a very small effect, but means the plane ends up
  205.                 // pointing downwards in a stall
  206.                 m_Rigidbody.rotation = Quaternion.Slerp(m_Rigidbody.rotation,
  207.                                                       Quaternion.LookRotation(m_Rigidbody.velocity, transform.up),
  208.                                                       m_AerodynamicEffect*Time.deltaTime);
  209.             }
  210.         }
  211.  
  212.  
  213.         private void CalculateLinearForces()
  214.         {
  215.             // Now calculate forces acting on the aeroplane:
  216.             // we accumulate forces into this variable:
  217.             var forces = Vector3.zero;
  218.             // Add the engine power in the forward direction
  219.             forces += EnginePower*transform.forward;
  220.             // The direction that the lift force is applied is at right angles to the plane's velocity (usually, this is 'up'!)
  221.             var liftDirection = Vector3.Cross(m_Rigidbody.velocity, transform.right).normalized;
  222.             // The amount of lift drops off as the plane increases speed - in reality this occurs as the pilot retracts the flaps
  223.             // shortly after takeoff, giving the plane less drag, but less lift. Because we don't simulate flaps, this is
  224.             // a simple way of doing it automatically:
  225.             var zeroLiftFactor = Mathf.InverseLerp(m_ZeroLiftSpeed, 0, ForwardSpeed);
  226.             // Calculate and add the lift power
  227.             var liftPower = ForwardSpeed*ForwardSpeed*m_Lift*zeroLiftFactor*m_AeroFactor;
  228.             forces += liftPower*liftDirection;
  229.             // Apply the calculated forces to the the Rigidbody
  230.             m_Rigidbody.AddForce(forces);
  231.         }
  232.  
  233.  
  234.         private void CalculateTorque()
  235.         {
  236.             // We accumulate torque forces into this variable:
  237.             var torque = Vector3.zero;
  238.             // Add torque for the pitch based on the pitch input.
  239.             torque += PitchInput*m_PitchEffect*transform.right;
  240.             // Add torque for the yaw based on the yaw input.
  241.             torque += YawInput*m_YawEffect*transform.up;
  242.             // Add torque for the roll based on the roll input.
  243.             torque += -RollInput*m_RollEffect*transform.forward;
  244.             // Add torque for banked turning.
  245.             torque += m_BankedTurnAmount*m_BankedTurnEffect*transform.up;
  246.             // The total torque is multiplied by the forward speed, so the controls have more effect at high speed,
  247.             // and little effect at low speed, or when not moving in the direction of the nose of the plane
  248.             // (i.e. falling while stalled)
  249.             m_Rigidbody.AddTorque(torque*ForwardSpeed*m_AeroFactor);
  250.         }
  251.  
  252.  
  253.         private void CalculateAltitude()
  254.         {
  255.             // Altitude calculations - we raycast downwards from the aeroplane
  256.             // starting a safe distance below the plane to avoid colliding with any of the plane's own colliders
  257.             var ray = new Ray(transform.position - Vector3.up*10, -Vector3.up);
  258.             RaycastHit hit;
  259.             Altitude = Physics.Raycast(ray, out hit) ? hit.distance + 10 : transform.position.y;
  260.         }
  261.  
  262.  
  263.         // Immobilize can be called from other objects, for example if this plane is hit by a weapon and should become uncontrollable
  264.         public void Immobilize()
  265.         {
  266.             m_Immobilized = true;
  267.         }
  268.  
  269.  
  270.         // Reset is called via the ObjectResetter script, if present.
  271.         public void Reset()
  272.         {
  273.             m_Immobilized = false;
  274.         }
  275.  
  276.         public void Update()
  277.         {  
  278.             SpeedDial.GetComponent<RotateSpeedDial>();
  279.             rb = this.GetComponent<Rigidbody>();
  280.             RotateSpeedDial.ShowSpeed(rb.velocity.magnitude,0,100);
  281.         }
  282.     }
  283. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement