♪__この大空に~翼を広げ~飛んで~行きた~い~よ~~__
という訳で、Unity(C#)で翼を作ってみたいと思います。
#要件
翼を作るからには、羽ばたきは必要でしょう。
個人的には、特に__滑空__に魅力を感じているので滑空も実装します。
#下調べ
全くの素人なので理論を少し調べてみました。
が、変数が多く、Unityで正確に実装できる気もしなかったのでハリボテ簡単に作ります。
#見た目
見た目がそれっぽい方が楽しそうなので、翼の画像を探します。
https://sige2005.exblog.jp/21725321/
で見つけた翼を使います。
本体は何となく緑のSphereと青い翼で、これらをFixedJointで繋ぎます。一気にそれっぽい!
#羽ばたきの試作1
翼は空気抵抗で飛んでるイメージなので、翼の空気抵抗を高めて下方向にAddForceすれば反作用で飛ぶのでは?
__→__そもそもまともに動かず、FixedJointの影響で本体ごと下に……
#羽ばたきの試作2
翼の空気抵抗を高めて下方向にAddForceした後、翼の空気抵抗を低めて上方向にAddForceすれば羽ばたきっぽくなるのでは?
__→__やはりFixedJointの影響で本体ごと上下に……もはや空気抵抗というより翼に引っ張られている。
#羽ばたきの試作3
空気抵抗で飛ぶという考えは捨てて、翼の動きは見た目だけにすればいいのでは?
→本体は普通にAddForceで浮かせ、翼の動きを合わせることで自然になった。
スクリプトがこちら
using UniRx;
using UnityEngine;
public class FlapByKey : MonoBehaviour
{
private Rigidbody rigidBody;
private Subject<Unit> wingUpSubject;
public Rigidbody parentRigidBody;
public float power;
private Subject<Unit> wingDownSubject;
private Subject<Unit> parentUpSubject;
// Use this for initialization
void Start()
{
wingUpSubject = new Subject<Unit>();
wingDownSubject = new Subject<Unit>();
parentUpSubject = new Subject<Unit>();
rigidBody = GetComponent<Rigidbody>();
wingUpSubject
.ThrottleFirst(System.TimeSpan.FromMilliseconds(500f))
.Subscribe(_ =>
{
rigidBody.AddForceAtPosition((transform.right.normalized + Vector3.up.normalized).normalized * 0.2f, transform.position);
wingDownSubject.OnNext(Unit.Default);
}
);
wingDownSubject
.Delay(System.TimeSpan.FromMilliseconds(100f))
.Subscribe(
_ =>
{
rigidBody.AddForceAtPosition(Vector3.down.normalized.normalized * 0.2f, transform.position);
parentUpSubject.OnNext(Unit.Default);
}
);
parentUpSubject
.Delay(System.TimeSpan.FromMilliseconds(200f))
.Subscribe(_ =>
{
parentRigidBody.AddForceAtPosition(parentRigidBody.transform.up.normalized * power, parentRigidBody.transform.position);
}
);
}
// Update is called once per frame
void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
wingUpSubject.OnNext(Unit.Default);
}
}
}
#滑空の試作 細かいことは無視して運動エネルギー保存則を使います。Unityで羽ばたいてみた pic.twitter.com/s2D9Gv5DJ7
— 35 (@v37X9D20MEGO8Nl) September 3, 2018
v = \sqrt{2g\Delta{h}}
スクリプトがこちら
using UnityEngine;
//羽につける用
public class GlindByKey : MonoBehaviour {
private Rigidbody rigidBody;
public Rigidbody parentRigidBody; //本体
private float glindStartedY;
private Vector3 glindStartedVelocity;
// Use this for initialization
void Start () {
rigidBody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
if (Input.GetKey(KeyCode.Mouse1))
{
float deltaY = glindStartedY - parentRigidBody.position.y;
if (deltaY >= 0)
{
parentRigidBody.velocity = parentRigidBody.transform.forward.normalized * Mathf.Sqrt(2 * Physics.gravity.magnitude * deltaY);
}
}
else
{
parentRigidBody.useGravity = true;
glindStartedY = parentRigidBody.position.y;
}
}
}
Unityで滑空してみた pic.twitter.com/GNbnxwlQVC
— 35 (@v37X9D20MEGO8Nl) September 8, 2018
#まとめ
現実の挙動に忠実でなくても楽しいですね。
これ使ってゲーム作りたい。