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++;
|
|
}
|
|
}
|
|
}
|
|
}
|