-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
This file was deleted.
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
using UnityEngine; | ||
|
||
public abstract class AircraftBase : MonoBehaviour | ||
{ | ||
public abstract Rigidbody Rigidbody { get; internal set; } | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using UnityEngine; | ||
|
||
public class CenterOfGravity : MonoBehaviour | ||
{ | ||
void Start() | ||
{ | ||
var rb = GetComponentInParent<Rigidbody>(); | ||
rb.centerOfMass = rb.transform.InverseTransformPoint(transform.position); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// | ||
// Copyright (c) Brian Hernandez. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for details. | ||
// | ||
|
||
using UnityEngine; | ||
using System; | ||
|
||
public class Helicopter : AircraftBase | ||
{ | ||
public bool EngineOn = false; | ||
|
||
public WeaponDropper[] weapons; | ||
|
||
public override Rigidbody Rigidbody { get; internal set; } | ||
|
||
private Rigidbody _hub; | ||
private HingeJoint _hinge; | ||
|
||
public int Rpm | ||
{ | ||
get | ||
{ | ||
var angVel = _hub.transform.InverseTransformVector(_hub.angularVelocity); | ||
return Mathf.Abs(Mathf.FloorToInt(angVel.y * 9.5493f)); | ||
} | ||
} | ||
|
||
private float _collective = 0f; | ||
public float Collective => _collective; | ||
|
||
private void Awake() | ||
{ | ||
Rigidbody = GetComponent<Rigidbody>(); | ||
_hinge = GetComponent<HingeJoint>(); | ||
_hub = _hinge.connectedBody; | ||
} | ||
|
||
private void Start() | ||
{ | ||
try | ||
{ | ||
Input.GetAxis("Yaw"); | ||
} | ||
catch (ArgumentException e) | ||
{ | ||
Debug.LogWarning(e); | ||
Debug.LogWarning(name + ": \"Yaw\" axis not defined in Input Manager. Tail rotor will not work correctly!"); | ||
} | ||
} | ||
|
||
void Update() | ||
{ | ||
if(Input.GetButtonDown("Jump")) | ||
{ | ||
EngineOn = !EngineOn; | ||
} | ||
|
||
_collective = (Input.GetAxis("Collective") + 1f) / 2f; | ||
|
||
if (weapons.Length > 0) | ||
{ | ||
if (Input.GetButtonDown("Fire3")) | ||
{ | ||
foreach (WeaponDropper dropper in weapons) | ||
{ | ||
dropper.Fire(Rigidbody.GetPointVelocity(dropper.transform.position)); | ||
} | ||
} | ||
} | ||
|
||
_hinge.useMotor = EngineOn; | ||
} | ||
|
||
private float CalculatePitchG() | ||
{ | ||
// Angular velocity is in radians per second. | ||
Vector3 localVelocity = transform.InverseTransformDirection(Rigidbody.velocity); | ||
Vector3 localAngularVel = transform.InverseTransformDirection(Rigidbody.angularVelocity); | ||
|
||
// Local pitch velocity (X) is positive when pitching down. | ||
|
||
// Radius of turn = velocity / angular velocity | ||
float radius = (Mathf.Approximately(localAngularVel.x, 0.0f)) ? float.MaxValue : localVelocity.z / localAngularVel.x; | ||
|
||
// The radius of the turn will be negative when in a pitching down turn. | ||
|
||
// Force is mass * radius * angular velocity^2 | ||
float verticalForce = (Mathf.Approximately(radius, 0.0f)) ? 0.0f : (localVelocity.z * localVelocity.z) / radius; | ||
|
||
// Express in G (Always relative to Earth G) | ||
float verticalG = verticalForce / -9.81f; | ||
|
||
// Add the planet's gravity in. When the up is facing directly up, then the full | ||
// force of gravity will be felt in the vertical. | ||
verticalG += transform.up.y * (Physics.gravity.y / -9.81f); | ||
|
||
return verticalG; | ||
} | ||
|
||
private void OnGUI() | ||
{ | ||
const float msToKnots = 1.94384f; | ||
GUI.Label(new Rect(10, 40, 300, 20), string.Format("Speed: {0:0.0} knots", Rigidbody.velocity.magnitude * msToKnots)); | ||
GUI.Label(new Rect(10, 60, 300, 20), string.Format("Collective: {0:0.0}%", _collective * 100.0f)); | ||
GUI.Label(new Rect(10, 80, 300, 20), string.Format("G Load: {0:0.0} G", CalculatePitchG())); | ||
GUI.Label(new Rect(10, 100, 300, 20), string.Format("Rotor RPM: {0}", Rpm)); | ||
} | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
using UnityEngine; | ||
|
||
[RequireComponent(typeof(Rigidbody))] | ||
public class RotorAssembly : MonoBehaviour | ||
{ | ||
public Helicopter Heli; | ||
public float MaxAngularVelocity = 400f; | ||
public float BladeLength = 5; | ||
public float MaxBladePitch = 10f; | ||
public float MinBladePitch = -5f; | ||
public float CyclicMaxPitch = 5f; | ||
|
||
private float _collective; | ||
private float _rollInput; | ||
private float _pitchInput; | ||
|
||
private Rigidbody _rb; | ||
private Quaternion[] _initialRotations; | ||
private FixedJoint[] _rotors; | ||
|
||
private void Start() | ||
{ | ||
_rb = this.GetComponent<Rigidbody>(); | ||
_rb.maxAngularVelocity = MaxAngularVelocity; | ||
|
||
_rotors = GetComponents<FixedJoint>(); | ||
_initialRotations = new Quaternion[_rotors.Length]; | ||
|
||
for(int i=0; i<_rotors.Length; i++) | ||
{ | ||
_rotors[i].connectedBody.maxAngularVelocity = MaxAngularVelocity; | ||
_initialRotations[i] = _rotors[i].connectedBody.transform.localRotation; | ||
} | ||
} | ||
|
||
private void Update() | ||
{ | ||
_collective = Heli.Collective; | ||
_rollInput = Input.GetAxis("Horizontal"); | ||
_pitchInput = Input.GetAxis("Vertical") * -1f; | ||
} | ||
|
||
private void FixedUpdate() | ||
{ | ||
var relwind = -Heli.Rigidbody.velocity; | ||
|
||
for (int i=0; i<_rotors.Length; i++) | ||
{ | ||
var holder = _rotors[i].connectedBody.transform; | ||
var rotor = holder.GetChild(0); | ||
var rvel = _rb.GetPointVelocity(rotor.transform.position) + relwind; | ||
var angle = Vector3.SignedAngle(holder.forward, Heli.transform.forward, Heli.transform.up); | ||
//var dot = Vector3.Dot(relwind.normalized, rvel.normalized); //use the dot product to simulate the effects of blade flapping (+1 == retreating blade; -1 == advancing blade) | ||
|
||
var rollCyclic = Mathf.Sin(angle * Mathf.Deg2Rad) * _rollInput; | ||
var pitchCyclic = Mathf.Cos(angle * Mathf.Deg2Rad) * _pitchInput; | ||
|
||
var cyclic = Mathf.Clamp(rollCyclic + pitchCyclic, -1f, 1f); | ||
|
||
var bladePitch = Mathf.Lerp(MinBladePitch, MaxBladePitch, _collective); | ||
bladePitch += cyclic * CyclicMaxPitch; | ||
|
||
rotor.transform.localRotation = Quaternion.AngleAxis(bladePitch, Vector3.left); | ||
} | ||
} | ||
} |