Skip to content

Instantly share code, notes, and snippets.

@kamino410
Last active May 16, 2018 03:02
Show Gist options
  • Select an option

  • Save kamino410/6454f1fdbe784adf587f3e2a5afa08ce to your computer and use it in GitHub Desktop.

Select an option

Save kamino410/6454f1fdbe784adf587f3e2a5afa08ce to your computer and use it in GitHub Desktop.
Unity C# script for AlbaSim; flight simulator of human powered aircraft (https://www.youtube.com/watch?v=gkGf1dIYQEk)
using UnityEngine;
using System.Collections;
class WingElem {
public WingElem(Vector3 pos, float dih, float coef, LineRenderer dlr, LineRenderer llr) {
Pos = pos;
var rad = Mathf.Deg2Rad * dih;
BeamVec = new Vector3(Mathf.Cos(rad), Mathf.Sin(rad), 0);
Normal = new Vector3(-Mathf.Sin(rad), Mathf.Cos(rad), 0);
Coef = coef;
DragLr = dlr;
LiftLr = llr;
}
public Vector3 Pos { get; private set; }
public Vector3 BeamVec { get; private set; }
public Vector3 Normal { get; private set; }
public float Coef { get; private set; }
public LineRenderer DragLr { get; private set; }
public LineRenderer LiftLr { get; private set; }
}
public class BehaviourScript : MonoBehaviour {
Rigidbody _rb;
Vector3 _liftPos;
Vector3 _elevPos;
Vector3 _radPos;
Vector3 _propPos;
WingElem[] _mainWingElems;
public GameObject Elev;
public GameObject Fin;
public GameObject Prop;
public UnityEngine.UI.Text Text;
public AudioClip Sound1;
public AudioClip Sound2;
public AudioClip Sound3;
public AudioClip Sound4;
public AudioSource SoundSource;
public LineRenderer DragLrR1;
public LineRenderer DragLrR2;
public LineRenderer DragLrR3;
public LineRenderer DragLrR4;
public LineRenderer DragLrR5;
public LineRenderer DragLrL1;
public LineRenderer DragLrL2;
public LineRenderer DragLrL3;
public LineRenderer DragLrL4;
public LineRenderer DragLrL5;
public LineRenderer LiftLrR1;
public LineRenderer LiftLrR2;
public LineRenderer LiftLrR3;
public LineRenderer LiftLrR4;
public LineRenderer LiftLrR5;
public LineRenderer LiftLrL1;
public LineRenderer LiftLrL2;
public LineRenderer LiftLrL3;
public LineRenderer LiftLrL4;
public LineRenderer LiftLrL5;
private Vector3 _pos;
private Vector3 _vv;
private Vector3 _bv;
private Vector3 _nv;
private float _v;
private int _sig;
private float _input;
private float _aoa;
private float _aoa1;
private float _aoa2;
private float _aoa3;
private float _aoa4;
private float _dcoef;
private float _lcoef;
private Vector3 _drag;
private Vector3 _lift;
private void Start() {
SoundSource.clip = Sound1;
SoundSource.loop = true;
SoundSource.Play();
_rb = GetComponent<Rigidbody>();
_rb.mass = 96;
_rb.maxAngularVelocity = 1;
_rb.maxDepenetrationVelocity = 1000;
_rb.inertiaTensor = new Vector3(100, 900, 900);
_rb.centerOfMass = new Vector3(0, 0.75f, -0.75f);
_rb.angularDrag = 1.5f;
_liftPos = new Vector3(0, 1.62f, -0.73f);
_elevPos = new Vector3(0, 1.62f, -6.085f);
_radPos = new Vector3(0, 1.62f, -6.685f);
_propPos = new Vector3(0, 1.62f, 1);
_mainWingElems = new WingElem[] {
new WingElem(new Vector3(0.199512810051965f, 0.0139512947488251f) + _liftPos, 4f, 0.273270874978926f, DragLrR1, LiftLrR1),
new WingElem(new Vector3(2.54378832816255f, 0.17787900804752f) + _liftPos, 4f, 2.93766190602346f, DragLrR2, LiftLrR2),
new WingElem(new Vector3(6.82252526225002f, 0.589874514918456f) + _liftPos, 7f, 2.67327233448135f, DragLrR3, LiftLrR3),
new WingElem(new Vector3(11.0264767733655f, 1.20572130032603f) + _liftPos, 9.7f, 2.04650701091014f, DragLrR4, LiftLrR4),
new WingElem(new Vector3(14.8016016718262f, 1.9532133425143f) + _liftPos, 13f, 1.0683210905325f, DragLrR5, LiftLrR5),
new WingElem(new Vector3(-0.199512810051965f, 0.0139512947488251f) + _liftPos, -4f, 0.273270874978926f, DragLrL1, LiftLrL1),
new WingElem(new Vector3(-2.54378832816255f, 0.17787900804752f) + _liftPos, -4f, 2.93766190602346f, DragLrL2, LiftLrL2),
new WingElem(new Vector3(-6.82252526225002f, 0.589874514918456f) + _liftPos, -7f, 2.67327233448135f, DragLrL3, LiftLrL3),
new WingElem(new Vector3(-11.0264767733655f, 1.20572130032603f) + _liftPos, -9.7f, 2.04650701091014f, DragLrL4, LiftLrL4),
new WingElem(new Vector3(-14.8016016718262f, 1.9532133425143f) + _liftPos, -13f, 1.0683210905325f, DragLrL5, LiftLrL5),
};
}
private void Update() {
Text.text = "FL:" + transform.position.y.ToString("0.00") + " m";
//推力
_input = Input.GetAxis("Vertical");
_rb.AddForceAtPosition(transform.forward * 2.8f * 9.8f * _input, transform.TransformPoint(_propPos));
Prop.transform.localEulerAngles += new Vector3(0, 0, -6 * Mathf.Sqrt(_input / 3.26531E-05f) * Time.deltaTime);
//重力
_rb.AddForce(0, -9.8f, 0, ForceMode.Acceleration);
addMainWingForce();
addElevForce();
addRadForce();
if (transform.position.y < 0.02) {
_count = 0;
var v = _rb.velocity.magnitude;
if (v < 2) {
if (SoundSource.clip != Sound1) {
SoundSource.clip = Sound1;
}
} else if (v < 4) {
if (SoundSource.clip != Sound2) {
SoundSource.clip = Sound2;
}
} else if (v < 6) {
if (SoundSource.clip != Sound3) {
SoundSource.clip = Sound3;
}
} else if (SoundSource.clip != Sound4) {
SoundSource.clip = Sound4;
}
if (v < 0.1f && SoundSource.volume != 0)
SoundSource.Stop();
else {
if (!SoundSource.isPlaying)
SoundSource.Play();
SoundSource.volume = Mathf.Sin(Mathf.PI * v / 9f);
}
} else {
_count++;
if (_count > 2) {
_count = 0;
SoundSource.Stop();
}
}
}
int _count;
private void addMainWingForce() {
foreach (var elem in _mainWingElems) {
_bv = transform.TransformVector(elem.BeamVec);
_nv = transform.TransformVector(elem.Normal);
_pos = transform.TransformPoint(elem.Pos);
_vv = Vector3.ProjectOnPlane(_rb.GetPointVelocity(_pos), _bv);
_v = Vector3.Project(_vv, transform.forward).magnitude;
_sig = Vector3.Dot(_vv, _nv) > 0 ? -1 : 1;
_aoa = Vector3.Angle(_vv, transform.forward) * _sig;
_aoa2 = _aoa * _aoa;
_aoa3 = _aoa * _aoa * _aoa;
_aoa4 = _aoa * _aoa * _aoa * _aoa;
_dcoef = 0.000004f * _aoa4
- 0.00002f * _aoa3
+ 0.0002f * _aoa2
+ 0.0019f * _aoa
+ 0.0175f;
if (_dcoef > 0.03f)
_dcoef = 0.03f;
_drag = -_vv * _v * _dcoef * elem.Coef;
_lcoef = 0.1f * _aoa + 1.0022f;
if (_lcoef > 1.2)
_lcoef = 1.2f;
else if (_lcoef < -0.8f)
_lcoef = -0.8f;
_lift = Vector3.Cross(_vv, _bv) * _v * _lcoef * elem.Coef;
_rb.AddForceAtPosition(_drag + _lift, _pos);
//if (elem.LiftLr != null)
// elem.LiftLr.SetPositions(new Vector3[] { _pos, _pos + _lift * 0.01f });
//if (elem.DragLr != null)
// elem.DragLr.SetPositions(new Vector3[] { _pos, _pos + _drag * 0.5f });
}
}
/// <summary>
/// 水平尾翼の影響
/// </summary>
private void addElevForce() {
_pos = transform.TransformPoint(_elevPos);
_vv = Vector3.ProjectOnPlane(_rb.GetPointVelocity(_pos), transform.right);
_v = Vector3.Project(_vv, transform.forward).magnitude;
_sig = Vector3.Dot(_vv, transform.up) > 0 ? -1 : 1;
_input = Input.GetAxis("Vertical2") * 5;
_aoa = Vector3.Angle(_vv, transform.forward) * _sig + 2 + _input;
_dcoef = 0.0004f * _aoa * _aoa + 0.0063f;
if (_dcoef > 0.05f)
_dcoef = 0.05f;
_drag = -_vv * _v * _dcoef * 1.2f;
_lcoef = 0.077f * _aoa;
if (_lcoef > 1.2f)
_lcoef = 1.2f;
else if (_lcoef < -1.2f)
_lcoef = -1.2f;
_lift = Vector3.Cross(_vv, transform.right) * _v * _lcoef * 1.2f;
_rb.AddForceAtPosition(_drag + _lift, _pos);
Elev.transform.localEulerAngles = new Vector3(_input, 0, 0);
Text.text += "\nV :" + _v.ToString("0.00") + " m/s";
//Debug.Log(_v + " " + transform.position.y);
}
/// <summary>
/// 垂直尾翼の影響
/// </summary>
private void addRadForce() {
_pos = transform.TransformPoint(_radPos);
_vv = Vector3.ProjectOnPlane(_rb.GetPointVelocity(_pos), transform.up);
_v = Vector3.Project(_vv, transform.forward).magnitude;
_sig = Vector3.Dot(_vv, transform.right) > 0 ? 1 : -1;
_input = Input.GetAxis("Horizontal2") * 10;
_aoa = Vector3.Angle(_vv, transform.forward) * _sig + _input;
_dcoef = 0.00035f * _aoa * _aoa + 0.006f;
if (_dcoef > 0.04f)
_dcoef = 0.04f;
_drag = -_vv * _v * _dcoef * 1.15f;
_lcoef = 0.075f * _aoa;
if (_lcoef > 1.1f)
_lcoef = 1.1f;
else if (_lcoef < -1.1f)
_lcoef = -1.1f;
_lift = Vector3.Cross(_vv, transform.up) * _v * _lcoef * 1.15f;
_rb.AddForceAtPosition(_drag + _lift, _pos);
Fin.transform.localEulerAngles = new Vector3(0, -_input, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment