using UnityEngine ;

using System.Collections ;

public class AreoTest : MonoBehaviour

{

// Create Transforms for each of the moveable parts

public Transform aileronLeft ;

public Transform aileronRight ;

public Transform stabilator ;

public Transform rudder ;

public Transform gearLeft ;

public Transform gearRight ;

public Transform gearNose ;

public Transform wheelLeft ;

public Transform wheelRight ;

public Transform wheelNose ;

// Set the sensitivity of the controls

public float roll_sensitivity = 18f ;

public float pitch_sensitivity = 5f ;

public float yaw_sensitivity = 2f ;

// Landing gear retraction/deplopyment speed

public float leftGearSpeed = 2f ;

public float rightGearSpeed = 2f ;

public float noseGearSpeed = 3f ;

// Set limits to the +/- angles of the control surfaces

public float aileronAngleLimit = 15f ;

public float stabilatorAngleLimit = 15f ;

public float rudderAngleLimit = 15f ;

public float weight = 14600F ;

public float thrust = 1 . 5F ;

public float wingArea = 50 . 0F ;

public float dragCoeffiecent = 0 . 021F ;

public float upForce = 0 . 0F ;

public float simLift = 0 . 0F ;

public float simDrag = 0 . 0F ;

public float liftPercentage ;

public float currentAirDensity ;

private Rigidbody rb ;

private float gravity ;

private float pitch = 0 . 0F ;

private float roll = 0 . 0F ;

// Keep track of which state the landing gear is in

private bool retracting = false ;

private float [ ] pressureDensity =

{

1 . 2F

, 1 . 1F

, 1 . 0F

, 0 . 91F

, 0 . 82F

, 0 . 74F

, 0 . 66F

, 0 . 59F

, 0 . 53F

, 0 . 47F

, 0 . 41F

, 0 . 36F

, 0 . 31F

, 0 . 27F

, 0 . 23F

, 0 . 19F

, 0 . 17F

, 0 . 14F

, 0 . 12F

, 0 . 10F

, 0 . 088F

, 0 . 075F

, 0 . 064F

, 0 . 054F

, 0 . 046F

, 0 . 039F

, 0 . 034F

, 0 . 029F

, 0 . 025F

, 0 . 021F

, 0 . 018F

, 0 . 015F

, 0 . 013F

, 0 . 011F

, 0 . 0096F

, 0 . 0082F

} ;

// Use this for initialization

void Start ( )

{

rb = GetComponent < Rigidbody > ( ) ;

// Assign the universal weight of gravity

gravity = Physics . gravity . magnitude ;

float tmpWeight = weight * 0 . 0001F ; // 10,000 Simograms = 1

weight = tmpWeight ;

// Assign values

rb . mass = tmpWeight ;

rb . drag = dragCoeffiecent ;

thrust = rb . mass * gravity ;

// Check current air density

StartCoroutine ( CheckAir ( ) ) ;

}

// Air is in kg/m3

IEnumerator CheckAir ( )

{

int tmp = 0 ;

for ( int d = 0 ; d < pressureDensity . Length ; d ++ )

{

tmp = tmp + 1000 ;

if ( transform . position . y <= tmp )

{

currentAirDensity = pressureDensity [ d ] ;

break ;

}

}

yield return ( 5 ) ; new WaitForSeconds

StartCoroutine ( CheckAir ( ) ) ;

}

void AreoPhysics ( )

{

// Angle of attack

float angle = Mathf . Atan2 ( transform . forward . y , transform . forward . z ) ;

float cL = LiftCoefficient ( angle ) ;

// Lift in Newtons

simLift = cL * ( ( currentAirDensity * rb . velocity . sqrMagnitude ) / 2 ) * wingArea ;

simLift = simLift * 0 . 0001F ;

float dragForce = dragCoeffiecent * ( ( currentAirDensity * rb . velocity . sqrMagnitude ) / 2 ) * wingArea ;

simDrag = dragForce * 0 . 0001F ; // 10,000 Kilograms = 1 Simogram

}

// Update is called once per frame

void Update ( )

{

// simLift mass

roll = Input . GetAxis ( "Horizontal" ) ;

pitch = Input . GetAxis ( "Vertical" ) ;

LandingGear ( ) ;

ControlSurfaces ( ) ;

}

void LandingGear ( )

{

// If g is pressed, retract/deploy landing gear

if ( Input . GetKeyDown ( "g" ) ) {

if ( retracting == false ) {

retracting = true ;

} else {

retracting = false ;

}

}

// Retracting the landing gear

if ( retracting ) {

// Target position for retraction of left gear

Quaternion gearLeftRetracted = Quaternion . Euler ( 0f, 0f, 90f ) ;

// Rotate smoothly toward target position

gearLeft . transform . localRotation = Quaternion . Slerp ( gearLeft . transform . localRotation ,

gearLeftRetracted, leftGearSpeed * Time . deltaTime ) ;

// Do the same for right landing gear

Quaternion gearRightRetracted = Quaternion . Euler ( 0f, 0f, - 90f ) ;

gearRight . transform . localRotation = Quaternion . Slerp ( gearRight . transform . localRotation ,

gearRightRetracted, rightGearSpeed * Time . deltaTime ) ;

// Do the same for nose landing gear

Quaternion gearNoseRetracted = Quaternion . Euler ( - 100f, 0f, 0f ) ;

gearNose . transform . localRotation = Quaternion . Slerp ( gearNose . transform . localRotation ,

gearNoseRetracted, noseGearSpeed * Time . deltaTime ) ;

wheelLeft . collider . enabled = false ;

wheelRight . collider . enabled = false ;

wheelNose . collider . enabled = false ;

} else { // Deploying the landing gear...

// Target position for retraction of left gear

Quaternion gearLeftDeployed = Quaternion . Euler ( 0f, 0f, 0f ) ;

// Rotate smoothly toward target position

gearLeft . transform . localRotation = Quaternion . Slerp ( gearLeft . transform . localRotation ,

gearLeftDeployed, leftGearSpeed * Time . deltaTime ) ;

// Do the same for right landing gear

Quaternion gearRightDeployed = Quaternion . Euler ( 0f, 0f, 0f ) ;

gearRight . transform . localRotation = Quaternion . Slerp ( gearRight . transform . localRotation ,

gearRightDeployed, rightGearSpeed * Time . deltaTime ) ;

// Do the same for nose landing gear

Quaternion gearNoseDeployed = Quaternion . Euler ( 0f, 0f, 0f ) ;

gearNose . transform . localRotation = Quaternion . Slerp ( gearNose . transform . localRotation ,

gearNoseDeployed, noseGearSpeed * Time . deltaTime ) ;

wheelLeft . collider . enabled = true ;

wheelRight . collider . enabled = true ;

wheelNose . collider . enabled = true ;

}

}

void ControlSurfaces ( )

{

// Move control surfaces

aileronRight . localRotation = Quaternion . Euler ( roll * aileronAngleLimit, aileronRight . rotation . y ,

aileronRight . rotation . z ) ;

aileronLeft . localRotation = Quaternion . Euler ( - roll * aileronAngleLimit, aileronLeft . rotation . y ,

aileronLeft . rotation . z ) ;

stabilator . localRotation = Quaternion . Euler ( - pitch * stabilatorAngleLimit, stabilator . rotation . y ,

stabilator . rotation . z ) ;

}

void FixedUpdate ( )

{

AreoPhysics ( ) ;

float speed = rb . velocity . magnitude ;

Debug . Log ( speed ) ;

// Vectors

Vector3 dragVector = ( - rb . velocity ) . normalized * simDrag ;

Vector3 liftVector = transform . up ;

Vector3 energyV3 = transform . forward * thrust ;

if ( speed > 260 )

{

energyV3 = transform . forward ;

}

liftPercentage = Mathf . Clamp ( ( simLift / weight ) , 0 ,1 . 05F ) ;

upForce = ( gravity * rb . mass ) * liftPercentage ;

liftVector = liftVector * upForce ;

rb . AddForce ( energyV3 - dragVector ) ;

rb . AddForce ( liftVector ) ;

// Add roll, pitch and yaw torques to rigidbody

rb . AddRelativeTorque ( pitch * roll_sensitivity, 0f, - roll * roll_sensitivity ) ;

//rb.AddRelativeTorque (0f, yaw*yaw_sensitivity, 0f);

Debug . DrawRay ( transform . position ,dragVector,Color . red ) ;

Debug . DrawRay ( transform . position ,liftVector,Color . green ) ;

}

// Appoximation of a typical curve showing section lift coefficient versus angle of attack for a cambered airfoil

float LiftCoefficient ( float rad )

{

float cL ;

float degrees = rad * Mathf . Rad2Deg ;

if ( degrees >= - 5 . 0F && degrees <= 25 . 0F )

{

cL = 1 . 5F * Mathf . Sin ( rad ) + 0 . 5F ;

}

else if ( degrees > 25 . 0F && degrees < 65 )

{

cL = 0 . 5F ;

}

// Stall

else {

cL = 0 . 05F ;

}

return cL ;

}