402 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			402 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using UnityEngine;
 | 
						|
 | 
						|
[Serializable]
 | 
						|
public class Jet : MonoBehaviour
 | 
						|
{
 | 
						|
	public Vehicle vehicle;
 | 
						|
	public GameObject[] landingGear;
 | 
						|
	public float landingGearScale;
 | 
						|
	public Transform[] hoverThrusters;
 | 
						|
	public ParticleRenderer mainThrusterParticles;
 | 
						|
	public ThrustCone mainThrusterCone;
 | 
						|
	public Transform[] mainThruster;
 | 
						|
	public LayerMask thrustMask;
 | 
						|
	public MeshCollider bodyCollider;
 | 
						|
	public WhirldLOD lod;
 | 
						|
 | 
						|
	public int hoverThrustFactor = 1;
 | 
						|
	public float hoverSteerFactor = 0.1f;
 | 
						|
	public float hoverAngDrag = 0.1f;
 | 
						|
	public float hoverLevelForceFactor = 0.2f;
 | 
						|
	public int flightThrustFactor = 5;
 | 
						|
	public float flightAngDrag = 0.1f;
 | 
						|
 | 
						|
	public float atmosDensity;
 | 
						|
	public Vector3 locvel;
 | 
						|
	public float speed;
 | 
						|
	public float pitch;
 | 
						|
	public float roll;
 | 
						|
	public float angleOfAttack;
 | 
						|
	public float stallFactor;
 | 
						|
 | 
						|
	private float grav;
 | 
						|
	private float mass;
 | 
						|
	private Vector3 inertiaTensor;
 | 
						|
	private Quaternion inertiaTensorRotation;
 | 
						|
 | 
						|
	public float lavaFloat = 0.1f;
 | 
						|
	public RaycastHit hit;
 | 
						|
 | 
						|
	public void InitVehicle(Vehicle veh)
 | 
						|
	{
 | 
						|
		vehicle = veh;
 | 
						|
		vehicle.specialInput = true; //Start out in landing mode
 | 
						|
 | 
						|
		mass = vehicle.myRigidbody.mass;
 | 
						|
		grav = -Physics.gravity.y * mass;
 | 
						|
		inertiaTensor = vehicle.myRigidbody.inertiaTensor;
 | 
						|
		inertiaTensorRotation = vehicle.myRigidbody.inertiaTensorRotation;
 | 
						|
	}
 | 
						|
 | 
						|
	public void Update()
 | 
						|
	{
 | 
						|
        if (!vehicle)
 | 
						|
        {
 | 
						|
            return;
 | 
						|
        }
 | 
						|
 | 
						|
        //Thruster Particles
 | 
						|
        Vector3 mainThrustPELocVel = mainThrusterParticles.gameObject.particleEmitter.localVelocity;
 | 
						|
		if (vehicle.specialInput)
 | 
						|
		{
 | 
						|
            foreach (Transform thruster in hoverThrusters)
 | 
						|
            {
 | 
						|
                thruster.gameObject.particleEmitter.emit = true;
 | 
						|
 | 
						|
                Vector3 pelocvel = thruster.gameObject.particleEmitter.localVelocity;
 | 
						|
                pelocvel.y = -vehicle.input.z;
 | 
						|
                thruster.gameObject.particleEmitter.localVelocity = pelocvel;
 | 
						|
 | 
						|
                thruster.gameObject.particleEmitter.minSize =
 | 
						|
                    thruster.gameObject.particleEmitter.maxSize =
 | 
						|
                    Mathf.Max(0.1f, vehicle.input.z * 0.3f);
 | 
						|
            }
 | 
						|
			if (lod.level == 0)
 | 
						|
			{
 | 
						|
                mainThrustPELocVel.x = vehicle.input.x;
 | 
						|
                mainThrustPELocVel.y = -vehicle.input.y;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				mainThrusterCone.magThrottle = 0f;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			if (vehicle.brakes)
 | 
						|
			{
 | 
						|
				vehicle.input.z = 0f;
 | 
						|
			}
 | 
						|
 | 
						|
			if (lod.level == 0)
 | 
						|
			{
 | 
						|
                mainThrustPELocVel.x = mainThrustPELocVel.y = 0.0f;
 | 
						|
            }
 | 
						|
			else
 | 
						|
			{
 | 
						|
				mainThrusterCone.magThrottle = 4f;
 | 
						|
			}
 | 
						|
 | 
						|
            foreach (Transform thruster in hoverThrusters)
 | 
						|
            {
 | 
						|
                thruster.gameObject.particleEmitter.emit = false;
 | 
						|
            }
 | 
						|
		}
 | 
						|
        mainThrustPELocVel.z = Mathf.Min(
 | 
						|
            -10.0f * (vehicle.specialInput ?
 | 
						|
                0.1f :
 | 
						|
                vehicle.input.z),
 | 
						|
            -0.5f);
 | 
						|
        if (mainThrustPELocVel.z >= -1)
 | 
						|
        {
 | 
						|
            mainThrusterParticles.particleRenderMode = ParticleRenderMode.Billboard;
 | 
						|
        }
 | 
						|
        else mainThrusterParticles.particleRenderMode = ParticleRenderMode.Stretch;
 | 
						|
        mainThrusterParticles.gameObject.particleEmitter.localVelocity = mainThrustPELocVel;
 | 
						|
 | 
						|
        //Camera
 | 
						|
		vehicle.camSmooth = !vehicle.specialInput;
 | 
						|
	}
 | 
						|
 | 
						|
	public void FixedUpdate()
 | 
						|
	{
 | 
						|
		if (!vehicle)
 | 
						|
		{
 | 
						|
            //We are materializing, don't try to manipulate physics
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
        //Landing Gear
 | 
						|
		if (vehicle.specialInput)
 | 
						|
		{
 | 
						|
            if (!landingGear[lod.level].active)
 | 
						|
            {
 | 
						|
                landingGear[lod.level].SetActiveRecursively(true);
 | 
						|
            }
 | 
						|
            if (landingGearScale < 1)
 | 
						|
            {
 | 
						|
                landingGearScale += Time.deltaTime;
 | 
						|
            }
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
            if (landingGear[lod.level].active &&
 | 
						|
                landingGearScale > 0)
 | 
						|
            {
 | 
						|
                landingGearScale -= Time.deltaTime;
 | 
						|
            }
 | 
						|
            else if (landingGear[lod.level].active)
 | 
						|
            {
 | 
						|
                landingGear[lod.level].SetActiveRecursively(false);
 | 
						|
            }
 | 
						|
		}
 | 
						|
        if (landingGear[lod.level].active)
 | 
						|
        {
 | 
						|
            Vector3 locscl = landingGear[lod.level].transform.localScale;
 | 
						|
            locscl.y =
 | 
						|
                locscl.x =
 | 
						|
                landingGearScale;
 | 
						|
            landingGear[lod.level].transform.localScale = locscl;
 | 
						|
        }
 | 
						|
 | 
						|
		if (vehicle.myRigidbody.isKinematic)
 | 
						|
		{
 | 
						|
            //We are materializing, don't try to manipulate physics
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		vehicle.myRigidbody.centerOfMass = Vector3.zero;
 | 
						|
		vehicle.myRigidbody.inertiaTensor = inertiaTensor * 0.75f;
 | 
						|
		vehicle.myRigidbody.inertiaTensorRotation = inertiaTensorRotation;
 | 
						|
 | 
						|
        //Hovering
 | 
						|
		if (vehicle.specialInput)
 | 
						|
		{
 | 
						|
            //Force of hover thrusters in atmosphere
 | 
						|
			vehicle.myRigidbody.AddForce(
 | 
						|
                transform.up *
 | 
						|
                vehicle.input.z *
 | 
						|
                hoverThrustFactor *
 | 
						|
                grav);
 | 
						|
			
 | 
						|
            //Autoleveling
 | 
						|
            vehicle.myRigidbody.AddTorque(
 | 
						|
                Vector3.Cross(transform.up, Vector3.up) *
 | 
						|
                Vector3.Angle(transform.up, Vector3.up) *
 | 
						|
                hoverLevelForceFactor *
 | 
						|
                mass);
 | 
						|
			
 | 
						|
            //Steering
 | 
						|
            vehicle.myRigidbody.AddRelativeTorque(new Vector3(
 | 
						|
                vehicle.input.y * mass * hoverSteerFactor,
 | 
						|
                Mathf.Clamp(vehicle.input.x + vehicle.input.w, -1f, 1f) * mass * hoverSteerFactor,
 | 
						|
                vehicle.input.x * -1f * mass * hoverSteerFactor));
 | 
						|
			
 | 
						|
            vehicle.myRigidbody.drag =
 | 
						|
                Game.Settings.jetHDrag *
 | 
						|
                vehicle.myRigidbody.velocity.magnitude *
 | 
						|
                (float)(vehicle.brakes ? 7 : 1);
 | 
						|
			vehicle.myRigidbody.angularDrag =
 | 
						|
                hoverAngDrag *
 | 
						|
                (float)(vehicle.brakes ? 5 : 1);
 | 
						|
            mainThruster[lod.level].localEulerAngles = Vector3.zero;
 | 
						|
		}
 | 
						|
 | 
						|
        //Flying
 | 
						|
		else
 | 
						|
		{
 | 
						|
			if (vehicle.brakes)
 | 
						|
			{
 | 
						|
				vehicle.input.z = 0f;
 | 
						|
			}
 | 
						|
 | 
						|
            //Pertinent Flight Info
 | 
						|
			if (vehicle.myRigidbody.transform.position.y < 5000f)
 | 
						|
			{
 | 
						|
				atmosDensity = Mathf.Lerp(
 | 
						|
                    1.225f,
 | 
						|
                    0.18756f,
 | 
						|
                    vehicle.myRigidbody.transform.position.y / 5000f);
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				atmosDensity = Mathf.Lerp(
 | 
						|
                    0.18756f,
 | 
						|
                    0.017102f,
 | 
						|
                    vehicle.myRigidbody.transform.position.y / 10000f);
 | 
						|
			}
 | 
						|
			speed = vehicle.myRigidbody.velocity.magnitude;
 | 
						|
            pitch = (transform.eulerAngles.x > 180 ?
 | 
						|
                transform.eulerAngles.x - 360 :
 | 
						|
                transform.eulerAngles.x);
 | 
						|
			roll = ((transform.eulerAngles.z > 180f) ?
 | 
						|
                (transform.eulerAngles.z - 360f) :
 | 
						|
                transform.eulerAngles.z);
 | 
						|
			locvel = vehicle
 | 
						|
                .myRigidbody
 | 
						|
                .transform
 | 
						|
                .InverseTransformDirection(vehicle.myRigidbody.velocity);
 | 
						|
			angleOfAttack = locvel.normalized.y;
 | 
						|
			if (speed < (float)Game.Settings.jetStall)
 | 
						|
			{
 | 
						|
				stallFactor = Mathf.Lerp(
 | 
						|
                    1f,
 | 
						|
                    0f,
 | 
						|
                    (speed - (float)Game.Settings.jetStall * 0.8f) /
 | 
						|
                        (float)Game.Settings.jetStall * 10f);
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				stallFactor = Mathf.Max(
 | 
						|
                    0f,
 | 
						|
                    Mathf.Min(
 | 
						|
                        Mathf.Abs(angleOfAttack) - 0.65f,
 | 
						|
                        0.1f
 | 
						|
                    )
 | 
						|
                ) * 10f;
 | 
						|
			}
 | 
						|
 | 
						|
            //Thruster
 | 
						|
            mainThruster[lod.level].localEulerAngles = new Vector3(
 | 
						|
                -vehicle.input.y * Mathf.Lerp(
 | 
						|
                    20,
 | 
						|
                    5,
 | 
						|
                    speed / (Game.Settings.jetStall * 5)),
 | 
						|
                -vehicle.input.x +
 | 
						|
                    (vehicle.input.w == 0 ?
 | 
						|
                        Mathf.Clamp(-locvel.x * 1, -10, 10) :
 | 
						|
                        Mathf.Clamp(-locvel.x * 0.5f, -10, 10)) +
 | 
						|
                    -vehicle.input.w * 15,
 | 
						|
                0);
 | 
						|
            vehicle.myRigidbody.AddForceAtPosition(
 | 
						|
                mainThruster[lod.level].forward *
 | 
						|
                    vehicle.input.z *
 | 
						|
                    flightThrustFactor *
 | 
						|
                    grav *
 | 
						|
                    0.99f,
 | 
						|
                mainThruster[0].position);
 | 
						|
			
 | 
						|
            //Control Surfaces
 | 
						|
            vehicle.myRigidbody.AddRelativeTorque(
 | 
						|
                new Vector3(
 | 
						|
                    vehicle.input.y *
 | 
						|
                        mass *
 | 
						|
                        (float)Game.Settings.jetSteer *
 | 
						|
                        0.2f,
 | 
						|
                    0f,
 | 
						|
                    vehicle.input.x *
 | 
						|
                        -1f *
 | 
						|
                        mass *
 | 
						|
                        (float)Game.Settings.jetSteer *
 | 
						|
                        0.75f
 | 
						|
                    ) *
 | 
						|
                Mathf.Lerp(
 | 
						|
                    0f,
 | 
						|
                    1f,
 | 
						|
                    speed / (float)Game.Settings.jetStall * 0.7f
 | 
						|
                ) *
 | 
						|
                atmosDensity *
 | 
						|
                ((locvel.z > 0f) ? 1 : -1));
 | 
						|
			vehicle.myRigidbody.angularDrag = flightAngDrag;
 | 
						|
			
 | 
						|
            //Lift
 | 
						|
            if (stallFactor < 1f)
 | 
						|
			{
 | 
						|
                //http://www.aerospaceweb.org/question/aerodynamics/q0015b.shtml
 | 
						|
				int wingArea = 15;
 | 
						|
				float liftCoefficient = ((angleOfAttack > 0f) ?
 | 
						|
                    (Mathf.Min(0.3f, angleOfAttack) * -1f) :
 | 
						|
                    Mathf.Max(0.3f * -1f, angleOfAttack * -1f));
 | 
						|
				float lift = Game.Settings.jetLift *
 | 
						|
                    atmosDensity *
 | 
						|
                    locvel.z *
 | 
						|
                    locvel.z *
 | 
						|
                    (float)wingArea *
 | 
						|
                    liftCoefficient;
 | 
						|
				vehicle.myRigidbody.AddRelativeForce(
 | 
						|
                    Vector3.up *
 | 
						|
                    Mathf.Lerp(lift, 0f, stallFactor));
 | 
						|
			}
 | 
						|
 | 
						|
            //Drag
 | 
						|
			if (stallFactor >= 0.5f)
 | 
						|
			{
 | 
						|
				vehicle.myRigidbody.drag =
 | 
						|
                    speed *
 | 
						|
                    Mathf.Lerp(
 | 
						|
                        Game.Settings.jetDrag,
 | 
						|
                        Game.Settings.jetDrag * 5f,
 | 
						|
                        Vector3.Angle(
 | 
						|
                            vehicle.myRigidbody.velocity,
 | 
						|
                            vehicle.myRigidbody.transform.forward
 | 
						|
                        ) / 90f
 | 
						|
                    ) *
 | 
						|
                    atmosDensity;
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				vehicle.myRigidbody.drag = 0f;
 | 
						|
				vehicle.myRigidbody.AddRelativeForce(
 | 
						|
                    new Vector3(
 | 
						|
                        locvel.x * (Game.Settings.jetDrag * -1f) * 3f,
 | 
						|
                        locvel.y * (Game.Settings.jetDrag * -1f) * 3f,
 | 
						|
                        locvel.z * (Game.Settings.jetDrag * -1f)
 | 
						|
                    ) *
 | 
						|
                        atmosDensity * (vehicle.brakes ? 5 : 1),
 | 
						|
                    ForceMode.VelocityChange);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
        //Floating
 | 
						|
        if (
 | 
						|
            transform.position.y < Game.Settings.lavaAlt + 20 ||
 | 
						|
            Physics.Raycast(
 | 
						|
                transform.position + (Vector3.up * 200),
 | 
						|
                Vector3.down,
 | 
						|
                out hit,
 | 
						|
                220,
 | 
						|
                1 << 4))
 | 
						|
		{
 | 
						|
            Vector3 up = Vector3.up * 200f;
 | 
						|
            Vector3 dn = -Vector3.up;
 | 
						|
            RaycastHit lavaHit;
 | 
						|
            for (int i = 0; i < bodyCollider.sharedMesh.vertices.Length; i++)
 | 
						|
            {
 | 
						|
                Vector3 pt = bodyCollider.sharedMesh.vertices[i];
 | 
						|
 | 
						|
                float hitDistance;
 | 
						|
                pt = transform.TransformPoint(pt);
 | 
						|
                if (pt.y < Game.Settings.lavaAlt)
 | 
						|
                {
 | 
						|
                    hitDistance = -(pt.y - Game.Settings.lavaAlt);
 | 
						|
                }
 | 
						|
                else if (
 | 
						|
                    hit.distance != 0.0f &&
 | 
						|
                    hit.collider.Raycast(new Ray(pt + up, dn), out lavaHit, 200f))
 | 
						|
                {
 | 
						|
                    hitDistance = (200 - lavaHit.distance);
 | 
						|
                }
 | 
						|
                else continue;
 | 
						|
                Vector3 ptVel = vehicle.myRigidbody.GetPointVelocity(pt);
 | 
						|
                vehicle.myRigidbody.AddForceAtPosition(
 | 
						|
                    (Vector3.up *
 | 
						|
                        lavaFloat *
 | 
						|
                        Mathf.Min(6, 3 + hitDistance) *
 | 
						|
                        Mathf.Lerp(
 | 
						|
                            1.3f,
 | 
						|
                            5,
 | 
						|
                            new Vector2(ptVel.x, ptVel.z).magnitude / 20) +
 | 
						|
                        ptVel *
 | 
						|
                        -Game.Settings.jetDrag * 70
 | 
						|
                    ) / bodyCollider.sharedMesh.vertexCount,
 | 
						|
                    pt,
 | 
						|
                    ForceMode.VelocityChange);
 | 
						|
 | 
						|
                bodyCollider.sharedMesh.vertices[i] = pt;
 | 
						|
                i++;
 | 
						|
            }
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |