BETA

OnParticleCollisionの使い方

投稿日:2018-11-03
最終更新:2018-11-03

OnParticleCollisionとは

OnCollisionEnter 等の衝突検知してくれる系関数の、パーティクル版みたいな感じです。

https://twitter.com/pwhrhs/status/1053943424829681664

パーティクル一粒一粒とコライダーの衝突を検知したときに呼び出されます。

ちなみに衝突位置などのパーティクルの衝突情報は ParticleCollisionEvent クラスで得られます。

準備

パーティクルは各自でお好きなものをご用意ください。

まず、OnParticleCollision を使うには、ParticleSystemの設定をいじってやる必要があります。 といってもやることは簡単で、Collision の Send Collision Messages にチェックをいれるだけです。

また、動的なオブジェクトとの衝突をとる場合は Enable Dynamic Collders にもチェックが必要です。

スクリプトで衝突を検知

次にスクリプトを作成します。まずは簡単なものから、

void OnParticleCollision(GameObject obj) {
        Debug.Log("衝突");
    }

OnParticleCollisionではGameObject型の引数が渡されます。

次に、魔法(パーティクル)に当たった敵が消えるというスクリプトを書いてみます。 (あまりお行儀の良いスクリプトではないかもです…)

private void OnParticleCollision(GameObject obj)
    {
        Debug.Log("何かと衝突しました");

        if (obj.tag == "Enemy")
        {
            Debug.Log("敵と衝突しました");
            obj.SetActive(false);
        }      
    }

ちなみに、OnCollisionEnter等と同様にyield文を使ってコルーチンにすることができるようです。

↓このスクリプトを使った動画。(今気付いたのですが、Qrunchって動画埋め込み無理?)

https://www.youtube.com/watch?v=LVGtXc42I

お気づきの方もいらっしゃるかもしれませんが、OnParticleCollisionではパーティクル一粒一粒の衝突が検知されるので、このスクリプトの場合では、

こんな感じに何回も関数が呼び出されるため、無用なSetActiveが発生してしまいます。

そのため、基本的には OnParticleCollision はダメージ計算に使われることが多いようです。(一粒子当たるごとに1ダメージみたいな)

private void OnParticleCollision(GameObject obj)
    {
        //ダメージ処理、やる気があれば更新します…
    }

OnParticleCollision の謎

かなり便利な OnParticleCollision なのですが、使っているうちにわからないところが出てきたのでまとめておきます。未解決のものもあるので、良ければ知恵をお貸しください。

Unityのバージョンは 2018.2.14f1 です。

衝突検知が起こらない(解決済み)

初歩的なものでは、コライダーの設定ミス、先に説明した Send Collision Messages や Enable Dynamic Collders にチェックが入ってない等が考えられますが、自分の場合、そこは大丈夫なのにうまく動作しない。

色々調べて見たところ、まったく移動しないパーティクルはUnityの物理演算の仕様上、衝突判定が起こらないようです。

OnParticleCollision関数を使ったスクリプトのアタッチ位置(原因不明)

以下のスクリプトを ①空のオブジェクトに

②衝突判定をしてほしいパーティクルのオブジェクトに

アタッチしたところ、

private void OnParticleCollision(GameObject obj)
    {
        Debug.Log("何かと衝突しました");

        if (obj.tag == "Enemy")
        {
            Debug.Log("敵と衝突しました");
        }   
    }

①ではログに「何かと衝突しました」しか表示されませんでした。②は「敵と衝突しました」も表示されます。

ノータイムでDestoyするとUnityが落ちる

以下のスクリプトで実行したところ、敵とパーティクルが衝突した瞬間Unityが落ちてしまいました。

private void OnParticleCollision(GameObject obj)
    {
        if (obj.tag == "Enemy")
        {
            Destroy(obj);
        }     
    }

何回も関数呼んでるのが原因な気がします。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@horukasuの技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!