【開発メモ】遠距離攻撃を近接攻撃で弾く処理の実装

というわけで、今回のお題は「遠距離攻撃を近接攻撃で弾く」です

shot2ss20160811131212641

敵が放った遠距離攻撃を剣で弾いてしまうものです!
多数を相手にすることが多くなる(予定)なので、遠距離攻撃はなかなか厄介な攻撃になります。
それをパキーンと弾いたりできればテンション上がりますね!

別に弾かずに消してしまってもゲーム的には全く問題ないのですが、やはりパキーンと弾いた方が見栄えはいいです。
「ダークソウル2」でも「スペルパリィ」という似たようなアクションがありました。
(リスクとリターン全く釣り合わないアレなものでしたが・・・)

遠距離攻撃の仕組みについては (やや古いですが) 以下の記事をご参照下さい。
要約すると「発射したキャラの前方をrigidbody.velocityに設定」することで飛ばしています。

【再編集】Unity開発メモまとめ 「攻撃処理系」

剣を遠距離攻撃に当てた際の判定

手始めに「剣が遠距離攻撃に当たったら弾を消す」という処理を考えてみます。
流石に遠距離攻撃全てを弾けるのもアレなので、「パキーンできる遠距離攻撃か」を敵キャラクターの攻撃に付いているクラスに持たせてしまいます。

using UnityEngine;
using System.Collections;

public class EnemyBulletHit : EnemyHit {

    public float bulletSpeed;
    public bool canReflect;

    protected Vector3 forward;
    private Rigidbody rb;

    protected override void Start() {
        base.Start();

        forward = hitManager.transform.forward;

        rb = this.GetComponent<Rigidbody>();
    }

    protected override void Update() {
        base.Update();

        rb.velocity = forward * bulletSpeed;
    }

    protected override void OnTriggerEnter(Collider c) {
        base.OnTriggerEnter(c);
    }
}

既存で作ってあるクラスなので長いですが、canReflect というフィールドを追加しただけです。
public なので、適当に getComponent() すれば判定できます。
攻撃判定の細かい処理まで記載すると長くなるので割愛させて頂きます。

「剣(近接攻撃)の判定に当たったら削除」するので、プレイヤーの近接攻撃判定に付けているクラスに処理を加えます。
ちょうど攻撃判定処理を継承している CloseRangeHit というジャストなクラスが付いていたりします。

using UnityEngine;
using System.Collections;

public class CloseRangeHit : PlayerHit {

    protected override void Start () {
        base.Start();
    }

    protected override void Update () {
        base.Update();
    }

    protected override void OnTriggerEnter (Collider c)    {
        base.OnTriggerEnter(c);

        if (c.gameObject.tag == "EnemyHit") {
            if (c.GetComponent<EnemyBulletHit>().canReflect) {
                Destroy(c.gameObject);
            }
        }
    }
}

追加したのは OnTriggerEnter() のif文です。
「当たったオブジェクトのタグがEnemyHit」且つ「canReflect がtrueで弾くことが可能」な場合、Destory() で遠距離攻撃判定を消してしまいます。

遠距離攻撃を弾く処理

次に遠距離攻撃を消すのではなく、どこか別の方向へ弾いてしまう場合の処理を考えます。
といっても割と単純で、if文で判定後に EnemyBulletHit の forward の値を変えてしまうだけです。
EnemyBulletHit に forward の値を書き換える用の関数を作成します。

public void changeForward(Vector3 vect) {
    forward = vect;
}

本当にセットするだけなので超単純!
もし弾に生存時間がある場合、このタイミングでコルーチンを再実行するのも良さそうですね。

追加した関数を CloseRangeHit の判定後に呼び出し、forward を変えます。
本来は攻撃判定の動きに合わせた方向に弾こうかと思いましたが、仕組み的にきつかったので単に逆側に跳ね返すようにしました。
その場合、enemyBulletHit の forward を正負を逆にするだけでOKです。

protected override void OnTriggerEnter (Collider c)    {
    base.OnTriggerEnter(c);

    if (c.gameObject.tag == "EnemyHit") {
        EnemyBulletHit enemyBulletHit = c.GetComponent<EnemyBulletHit>();

        if (enemyBulletHit.canReflect) {
            enemyBulletHit.changeForward(-enemyBulletHit.transform.forward);
        }
    }
}

動かしてみるとこんな感じです。

20160811_01

やや地味ですが、現状では十分でしょう。
そのうちそれっぽいエフェクトも作って、パキーンしたことを分かりやすくしたいですね。

まとめ

そんなわけで、「遠距離攻撃を弾き返す」処理について考えてみました!
遠距離攻撃で攻撃を割り込まれるのはどのゲームでも嫌なので、まぐれでも当たったら弾けるようにしたいです。

最近はかなりネタに困っていたりします。
現在やるべきことがステージ作りや敵キャラクター作りなど、割とセンスが求められる部分が多いため難航しております。
何か面白いものが出来たら紹介したいとは考えていますが・・・。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*