ゲーム制作勉強中!あこがれだったプログラマーに今からなろう!

昔あこがれだったプログラマー。今からでもUnityを勉強してみようと思い立ち、チャレンジ開始! Unity勉強メモや、悪戦苦闘な日々の記録です。

ドラゴンの吹っ飛ばし攻撃修正: 距離によって影響具合に変化をつける:3Dアクションゲームを作ろう(12)

ドラゴンの吹っ飛ばし攻撃の昨日の続き、ドラゴンとの距離によって影響具合を変える様に修正しよう。
修正方法は昨夜考えておいたので、それを形にしてみる。

まずドラゴンとプレイヤーの距離を算出する。
これは、昨夜の

    public void ScreamAttacking()
    {
        ScreamPS.Play(); //ここで衝撃波のParticleSystemを再生
        var heading=Target.transform.position-transform.position; //衝撃波の発生地点のベクトルを算出
        var direction = heading.normalized; 
        audioSource.PlayOneShot(DragonImpulseSE); 
        Target.GetComponent<Rigidbody>().AddForce(direction*8.7f, ForceMode.Impulse);
    }

で使ったheading変数をmagnitudeしてやればいい。

var distance=heading.magnitude;

距離が出たら、あとはこのdistanceで吹っ飛ばす力を割ってやれば、距離によって吹っ飛び方が変わってくれるはず😁

あと、衝撃波が下から来る様に、低い位置からAddForceしたかったが、ドラゴンの座標の基準点がドラゴンの上部にあるので、今のままでは、
プレイヤーより高い位置からのAddForceになってしまう。
Objectの高さを算出する方法をいろいろ調べてみて、RectTransformから算出する方法は見つけたのだけど、
今のドラゴンにはRectTransformはついていないし、このためだけにコンポーネントを追加したくはない😖
仕方がないので、ドラゴンの足の位置座標を、便宜上ドラゴンのtransform.position.y-1と仮定して作成する事にした。

   public void ScreamAttacking()
    {
        ScreamPS.Play();
        //ドラゴンの足元の座標を仮定してやる。
        Vector3 dragonLegsPos=new Vector3(transform.position.x,transform.position.y-1,transform.position.z);

        var heading=Target.transform.position-dragonLegsPos;
        var direction = heading.normalized;
        var distance=heading.magnitude; //ドラゴンとプレイヤー間の距離を算出

        if(distance<5) //距離が5以下なら吹っ飛ばし実行
        {
            audioSource.PlayOneShot(DragonInpalseSE);
                                            //距離に応じて、吹っ飛ばし力を減じている。
            Target.GetComponent<Rigidbody>().AddForce((direction*14.5f)/(distance/2), ForceMode.Impulse);
        }
    }

ついでに、ドラゴンがプレイヤーの方向を向くのが早すぎて、今のままではプレイヤーが攻撃できないので、それも修正する事にした。
今までは、単純にTarget(=プレイヤー)の方向にLookAtさせていたのだが、
「オブジェクトの方向をゆっくりと向く」で調べてみると、まさに今やりたい事にピッタリの記事を見つけたので

thinline196.hatenablog.com

早速、参考にゆっくり向きを変えるように修正してみた。

さらに、
今のままでは、例えばプレイヤーがジャンプするなどの、上下方向の移動をした際に、ドラゴンの角度が大変な事になってしまうので、それも修正する必要がある。

     Vector3 TargetDirection=new Vector3(Target.transform.position.x,
                                         transform.position.y,
                                         Target.transform.position.z);

     transform.rotation = Quaternion.Slerp(transform.rotation, 
                           Quaternion.LookRotation((TargetDirection - transform.position).normalized), 
                           RotationSpeed*Time.deltaTime);

Quaternion.Slerpは、第一引数の現在の方向、第二引数で向きたい方向、第三引数で回転速度をしてやると、第二引数で指定した方向に向かって、第三引数で指定した分だけ回転するという、まさにぴったりのメソッドだ。

第二引数の注意は、向きたい方向(ベクトル)で、向きたい座標(position)ではないということ🧐

向きたい方向は、Quaternion.LookRotation((TargetDirection - transform.position).normalized)で算出している。
この、TargetDirectionには、ターゲット(=プレイヤー)のx座標とz座標だけ利用することで、プレイヤーのy軸方向の位置、つまり上下の位置を無視して、向くべき座標を算出している。

ここまでの実際の動きはこんな感じ。

www.youtube.com

実際には、さっきのスクリプトに、さらにドラゴンの状態判定をして、衝撃波モードでは向きを変えるのを止めている。

このスキルとしては、だいぶ完成に近づいたかな〜