【Unity】パーティクルシステムの再生終了を検知する

こじゃらこじゃら

演出用のパーティクルを出し終わってもシーンにオブジェクトが残り続けてしまうみたいなの…😭

このはこのは

再生が終わったらオブジェクトを消す必要があるみたいね。これはパーティクルシステムの設定から簡単に出来るわ。

パーティクルの再生終了を検知して、オブジェクトを破棄したり非アクティブにしたりする方法の紹介です。

これは、ParticleSystemStopAction項目から設定できます。

この項目を設定すると、パーティクル再生が終了した時に特定のアクションを起こす事が可能です。

ただし、入れ子になったパーティクルや、Sub Emitterモジュールを使用している場合は、Unityバージョンによって挙動が違うので注意が必要です。

本記事では、StopAction項目の使い方を解説し、Unityバージョンによる挙動の違いにも触れます。

動作環境
  • Unity2021.2.1f1

スポンサーリンク

パーティクルの再生が終わったら破棄する

Particle System > Particle System > Stop Action項目Destroyに設定します。

実行結果

パーティクル再生が終了すると、ゲームオブジェクト自体が消滅していることが確認できます。

ただし、Looping項目などを有効にしてループ再生していると、再生が終了せず終了通知が呼ばれないためご注意ください。

破棄以外のアクション

Stop Actionには、Destroyを含め、次の4種類の設定項目が存在します。

  • None – 何もしない。初期設定。
  • Disable – オブジェクトを非アクティブにする。
  • Destroy – オブジェクトを破棄する。
  • Callback – OnParticleSystemStoppedメッセージをゲームオブジェクトにアタッチされたスクリプトに送信する。

参考:メインモジュール – Unity マニュアル

Disableで再生終了時に非アクティブにする

Stop Action項目にDisableに指定すると、パーティクルシステムの再生終了時にオブジェクトが非アクティブになります。

パーティクルを破棄せずに使いまわしたい場合に重宝するでしょう。

Callbackで再生終了時にスクリプトにメッセージ送信する

Stop Action項目にCallbackを指定すると、 パーティクルオブジェクトにアタッチされているスクリプトにOnParticleSystemStoppedメッセージが送信されるようになります。

次のようなスクリプトをパーティクルオブジェクトにアタッチして使います。

StopActionCallbackExample.cs
using UnityEngine;

public class StopActionCallbackExample : MonoBehaviour
{
    private void OnParticleSystemStopped()
    {
        print("パーティクルの再生が終了したよ!");
    }
}

注意点としては、必ずパーティクルオブジェクト自体にスクリプトがアタッチされている必要があり、子階層オブジェクトにアタッチされてもメッセージが送信されません。

Unityバージョンによる挙動の違い

パーティクルオブジェクトを入れ子にしていたり、Sub Emitterを使用している場合、Unityバージョンによって挙動が異なります。

旧バージョンと新バージョンでは次の違いがあります。

旧バージョン子階層やSub Emitterのパーティクルシステムが再生途中でも、親のパーティクルシステムの再生が終了するとStop Actionを実行する。
新バージョン子階層やSub Emitter、親のパーティクルシステムの再生がすべて終了してからStop Actionを実行する。

旧バージョンの挙動については、不具合として報告されており、以下のチケットで対応されています。

参考:Unity Issue Tracker – ParticleSystem.MainModule.stopAction does not wait till particles of the GameObject's child stop emitting before destroying

Unity2019の場合は2019.4.16f1以降、Unity2020の場合は2020.1.6f1または2020.2.0b2以降であれば新バージョンの挙動になります。

Unity2021でも新バージョンの挙動になります。

動作検証

Unityのバージョン違いによる挙動についても検証しました。

検証したバージョンは次の2つです。

  • 2020.1.5f1(旧バージョン)
  • 2020.1.6f1(新バージョン)

ヒエラルキーの構成は次の通り、入れ子にしたものとSub Emitterを使用したものの2パターンを再生し、Stop Actionにより再生終了したら破棄するようにします。

実行結果(2020.1.5f1)

親パーティクルの再生が終了すると、即座にStop Actionが実行されてパーティクルが消滅しています。

実行結果(2020.1.6f1)

子パーティクルやSub Emitterのパーティクル再生がすべて終了してからパーティクルオブジェクトが破棄されていることが確認できます。

さいごに

パーティクルシステムが再生したときのアクションは、Stop Actionから設定できます。

再生終了時に破棄や非アクティブ化したい場合は、ノーコーディングで実現できます。

子パーティクルやSub Emitterを使用しているときは、Unityバージョンによって挙動が異なることに注意が必要です。旧バージョンの動きは不具合扱いとして修正されています。

参考サイト

スポンサーリンク