20190413のUnityに関する記事は1件です。

【Unity】斜方投射の式を使って目標までの仰角を自動調整

はじめに

 Unityの物理エンジンとC#で目標までの距離に応じて仰角を自動で変えてくれる的なプログラムです。
独学なので、ソースコードの書き方等かなりガバがあるかもしれません。ご了承ください。

使用した式

斜方投射ーWikipedia
Wikipediaの斜方投射に関する式からお借りしました。
イラストが下手すぎてすみません。目標までの距離と初速度と重力加速度から、仰角θが求まるのでそれを使います。
ほうぶつ.png

ソースコードと実行結果

Luncher.csとBulletSc.csというそれぞれ発射台と弾につける二つのコードを書いてます。
乗せてるのはclassの中身だけで、とりあえず使ってないStart関数、Update関数をそれぞれ省いてます。
ランチャー側でいろいろ計算して、取得した弾インスタンスに値を渡しています。

Luncher.cs
    public GameObject Bullet;
    public float _Velocity_0;

    float _gravity = 9.8f;//重力加速度

    void Update(){
        //ランチャーの移動================================
        Vector2 pos = transform.position;
        pos.x += 0.1f * Input.GetAxisRaw("Horizontal");
        transform.position = pos;
        //================================================


        //スペースキーで弾の発射
        if (Input.GetKeyDown(KeyCode.Space)) {
            //ランチャーの座標取得
            Vector2 LuncherPos = transform.position;
            //ターゲットの座標取得
            Vector2 TargetPos = GameObject.Find("Target").transform.position;
            //ランチャーとターゲットの距離Lを取得
            float L = Vector2.Distance(LuncherPos, TargetPos);

             //Asinの中身を計算
            float AsinX = (L * _gravity) / (_Velocity_0 * _Velocity_0);
            if (AsinX >= 1) AsinX = 1.0f;//Asinの中身が1を超えるとまずいので

            //θ算出
            float _theta = 0.5f * Mathf.Asin(AsinX);
            //ターゲットとの位置関係で発射方向反転
            if (LuncherPos.x > TargetPos.x) _theta = Mathf.PI - 0.5f * Mathf.Asin(AsinX);


            //弾インスタンスを取得し、初速と発射角度を与える
            GameObject Bullet_obj = (GameObject)Instantiate(Bullet, transform.position, transform.rotation);
            BulletSc bullet_cs = Bullet_obj.GetComponent<BulletSc>();
            bullet_cs.Velocity_0 = _Velocity_0;
            bullet_cs.theta = _theta;
        }    
    }
BulletSc.cs
public float Velocity_0, theta;

    Rigidbody2D rid2d;
    void Start() {
        //Rigidbody取得
        rid2d = GetComponent<Rigidbody2D>();
        //角度を考慮して弾の速度計算
        Vector2 bulletV = rid2d.velocity;
        bulletV.x = Velocity_0 * Mathf.Cos(theta);
        bulletV.y = Velocity_0 * Mathf.Sin(theta);
        rid2d.velocity = bulletV;
    }

実行結果GIF 赤い四角がターゲットになります。
Qiita_1.gif
ターゲットとの位置関係で発射方向の切り替え
Qiita_2.gif

最後

発射した後の弾の処理はまったく考慮してないので、そのあたりはご了承ください。
今回の処理自体、汎用的というより用途はかなり局所的なものだと思います。何かの役に立ててもらえれば幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む