グレードソードソードに当たり判定をつけて、ユニティちゃんが岩を砕きます。

やっとここまできましたね(笑)

次は大詰めです。

グレードソードに当たり判定をつけていきましょう。

グレードソードをプレハブ化

前々回ぐらいで装備したグレードソード。

一応、プロジェクトウィンドウにドラッグし、原型プレハブとして残しておきます。

プレハブの編集モード

プレハブを開くから編集モードに切り替えます。

Colliderの追加

このコライダーというのが当たり判定用のオブジェクトになってくるのですごく重要です。

まず、コライダー用のゲームオブジェクトを追加します。

ゲームオブジェクトにコンポーネントの追加 > 物理 > ボックスコライダーをセットします。

緑枠がコライダー(当たり判定の領域になります)です。

Colliderの編集

コライダーの編集ボタンで編集モードに切り替えて、

3次元的にフィットするように調整します。

これを複数組み合わせてより細かな当たり判定の領域を作ることも出来ますし、メッシュデータを使うとメッシュコライダーとしてモデルそのままにコライダーをジャストフィットさせることが出来るらしい(未検証っす。)

ついでに、このコライダーをトリガーにします。

剣を振り回し、他のオブジェクトに当たった際に、トリガーになっていないと物理的に弾かれてしまいます。なので、上手く振り抜くことができなくなっちゃうのです。

逆にレースゲームなどで、弾かれた方がいい当たり判定の場合は、トリガーにしないほうが良いと思います。

Rigidbodyの追加

これがややこしいのですが、当たり判定を行う条件として、当てる方か当たる方、どちらかにリジッドボディが必要になります。(また、トリガーもどちらか一方がトリガーでは無い必要があるみたい)ややこしい……

今回は武器の方につけました。

重力は使用せずに、予期せぬ動きにならないよう位置なども固定させておきます。

スクリプトの追加

AttackCollision.cs などのファイル名で、

using UnityEngine;

public class AttackCollision : MonoBehaviour {

    public GameObject particleObject;

    private Animator anim;
    private AnimatorStateInfo currentBaseState;

    //攻撃モーションの判定用
    static int AttackTag = Animator.StringToHash("Attack");

    void Awake() {
        anim = gameObject.transform.root.gameObject.GetComponent<Animator>();
    }

    private void OnTriggerEnter(Collider col) {

        // 参照用のステート変数にBase Layer (0)の現在のステートを設定する
        currentBaseState = anim.GetCurrentAnimatorStateInfo(0);

        if (currentBaseState.tagHash == AttackTag) {

            //StoneObjectタグの付いたゲームオブジェクトと衝突したか判別
            if (col.gameObject.tag == "StoneObject") {
                //パーティクル用ゲームオブジェクト生成
                Instantiate(particleObject, col.ClosestPointOnBounds(this.transform.position), Quaternion.identity);
            }

        }
    }

}

このようなスクリプトを作成します。

private void OnTriggerEnter(Collider col)

OnTriggerEnter はコライダーの範囲内にオブジェクトが突き抜けてきたときに発生するイベントです。突入してきたColliderが引数として渡ってきます。

反対に、オブジェクトが突き抜けていく場合は、OnTriggerExitイベントになります。わかりやすい(笑)

(トリガーにしていない場合は、OnCollisionEnter イベントになるのですが、引数がColliderではなくCollisionになるという。超わかりにくい罠w)

 if (currentBaseState.tagHash == AttackTag) 

ここで攻撃モーションかどうかを判断し、

if (col.gameObject.tag == "StoneObject") {

一応、石のタグをもったゲームオブジェクトと接触した場合に限り、

Instantiate(particleObject, col.ClosestPointOnBounds(this.transform.position), Quaternion.identity);

接触した位置に、前回作成した演出用のパーティクルオブジェクトを追加する流れです。

スクリプトのアタッチ

コライダーオブジェクトにスクリプトを追加し、パーティクルオブジェクトに、前回作成したオブジェクトをドラッグして設定します。

これでプレハブの編集は終了ですので、保存して、シーンエディタに戻ります。

StoneObjectを作成

キューブオブジェクトを作成し、

ユニティちゃん側に移動する処理をつけていないので(爆)、目の前に配置させます。

タグに StoneObject を追加し、設定します。

試し切り

いよいよ試し切りです。

岩を砕きましたね♪

おまけ

大地にもStoneObjectのタグをつけてあげれば

グレードソードを振り下ろして、大地と接触した際にも演出が加わります♪

Unityでのゲーム基本がおぼろげながら見えてきました〜

この記事はユニティちゃんライセンス条項の元に提供されています。
© Unity Technologies Japan/UCL