LoginSignup
7
1

More than 5 years have passed since last update.

♪この大空に~(Unityで)翼を広げ~飛んで~行きた~い~よ~~

Posted at

この大空に~翼を広げ~飛んで~行きた~い~よ~~

という訳で、Unity(C#)で翼を作ってみたいと思います。

要件

翼を作るからには、羽ばたきは必要でしょう。
個人的には、特に滑空に魅力を感じているので滑空も実装します。

下調べ

全くの素人なので理論を少し調べてみました。
が、変数が多く、Unityで正確に実装できる気もしなかったのでハリボテ簡単に作ります。

見た目

見た目がそれっぽい方が楽しそうなので、翼の画像を探します。
https://sige2005.exblog.jp/21725321/
で見つけた翼を使います。
wingRight.png

本体は何となく緑のSphereと青い翼で、これらをFixedJointで繋ぎます。一気にそれっぽい!
キャプチャ.PNG

羽ばたきの試作1

翼は空気抵抗で飛んでるイメージなので、翼の空気抵抗を高めて下方向にAddForceすれば反作用で飛ぶのでは?
そもそもまともに動かず、FixedJointの影響で本体ごと下に……

羽ばたきの試作2

翼の空気抵抗を高めて下方向にAddForceした後、翼の空気抵抗を低めて上方向にAddForceすれば羽ばたきっぽくなるのでは?
やはりFixedJointの影響で本体ごと上下に……もはや空気抵抗というより翼に引っ張られている。

羽ばたきの試作3

空気抵抗で飛ぶという考えは捨てて、翼の動きは見た目だけにすればいいのでは?
→本体は普通にAddForceで浮かせ、翼の動きを合わせることで自然になった。
スクリプトがこちら

FlapByKey
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);
        }
    }
}


滑空の試作

細かいことは無視して運動エネルギー保存則を使います。

v = \sqrt{2g\Delta{h}}

スクリプトがこちら

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


まとめ

現実の挙動に忠実でなくても楽しいですね。
これ使ってゲーム作りたい。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1