Version: 2020.3
言語: 日本語
ビルトインのパーティクルシステムの例
車両からの排気煙の作成

簡易な爆発の作成

パーティクルシステムを使用することでリアルな爆発を引き起こすことができますが、その仕組みは、見た目より少し複雑です。爆発の実体は、単にパーティクルの外側への飛散ですが、それをずっとリアルに見せるために使える、簡単な修正方法がいくつかあります。

 開発中のパーティクルシステムによる爆発
開発中のパーティクルシステムによる爆発

パーティクルのタイムライン

単純な爆発は、全方向へ高速で弾け飛ぶ火の玉を生成します。最初の爆発はエネルギーが大きいため、非常に熱く (つまり、明るく) 高速で動きます。このエネルギーは急速に消散し、その結果、炎の拡大が遅くなり、さらに、冷却 (つまり、明るさが減少) します。最後に、すべての燃料が使い尽くされるにつれ炎が消えてゆき、やがて完全に消滅します。

爆発のパーティクルは通常、短い生存期間しかありません。その生存期間中にいくつかの特性を変化させて、効果をシミュレーションできます。パーティクルは非常に高速で移動するところから開始しますが、それは爆発の中心から離れるにつれて、大幅に減速します。また、色は始めは明るく、その後暗くなり、最終的には透明になっていきます。最後に、生存期間を通してパーティクルのサイズを減少していくと、燃料が使い果たされるにつれ炎が消失するような効果が得られます。

実装

デフォルトのパーティクルシステムオブジェクト (GameObject > Effects > Particle System) を開き、 Shape モジュールに移動し、エミッターの Shape を小さな Sphere、例えば Radius を約 0.5 ユニットに設定します。スタンダードアセットのパーティクルには、爆発に非常に適した ParticleFireball というマテリアルが含まれています (Unity のスタンダードアセットパッケージをまだインストールしていない場合は、スタンダードアセット を参照してください。Renderer モジュールを使用して、このマテリアルをシステムに設定することができます。ParticleFirecloudRenderer を開いた状態で、 Cast ShadowsReceive Shadows を無効にします。なぜなら、爆発の炎は光を受け取るのではなく放つからです。

この段階では、パーティクルは、中心点から外に向かって投げられるたくさんの小さな火の玉のように見えます。もちろん、爆発ではいっぺんに多くのパーティクルのバーストを作成する必要があります。Emission モジュールで、Rate 値を 0 に設定し、Time が 0 の時点にパーティクルの Burst を 1 つ追加します。バーストのパーティクル数は、爆発の大きさや強さに依存しますが、約50 パーティクルくらいから始めるとよいでしょう。バーストを設定するとより爆発のように見え始めますが、まだゆっくりで、炎が長時間継続します。Particle System モジュール (名前は、例えば Explosion のように、ゲームオブジェクトと同じ名前です) では、システムの Duration とパーティクルの Start Lifetime を両方とも 2 秒に設定します。

また、 Size Over Lifetime モジュールを使用して、燃料を使いきる炎の効果を作成することができます。「下降傾斜」のプリセット (つまり、サイズは100 %で始まり、0 に向かって減少します) を使用してサイズのカーブを設定します。炎を暗く薄れさせていくためには、Color Over Lifetime モジュールを有効にし、カーブの左端が白で始まり、右側で黒で終了するようなグラデーションに設定します。Fire Add マテリアルはレンダリングに追加シェーダーを使用するので、color プロパティの暗さもまた、パーティクルの透明度を制御します。色が黒く薄れていくにつれ、炎は完全に透明になります。また、付加するマテリアルは、互いの上に重ねて描画すると、パーティクルの明るさを増加することができます。これは、パーティクルすべてが近くにまとまっている爆発の開始時に、明るいフラッシュの印象をさらに強くするのに役立ちます。

現状では、爆発はそれらしくはなってきていますが、まるで宇宙で起こっているように見えます。パーティクルは放出され、フェードする前に一定の速度で長い距離を進みます。ゲームが宇宙に設定されているならば、これは望んでいる正確な効果かもしれません。しかし、大気中で起こる爆発は、周囲の空気によって遅くなり、減衰します。Limit Velocity Over Lifetime モジュールを有効にし、Speed をおよそ3.0に、Dampen をおよそ 0.4 に設定すると、それが進むにつれて爆発が少しずつ力を失っていく様子が表現されます。

最後に気を付けるのは、パーティクルが爆発の中心から遠ざかるにつれて、個々の形状がより認識できるようになるという点です。具体的には、同じ大きさで同じ回転をするパーティクルを表示すると、同じグラフィックスが各パーティクルで再利用されていることが明らかになってしまいます。これを回避するためには、パーティクルが生成されるときに、サイズと回転にランダムな値を加えます。インスペクターの上部にある Particle System モジュールで、Start SizeStart Rotation プロパティの右側にある小さな矢印をクリックし、その両方を Random Between Two Constants に設定してください。回転の場合、0 と 360 の 2 つの値を設定します (つまり、完全にランダムな回転)。サイズに関しては、大きすぎたり小さすぎたりするパーティクルを作らないようにすると同時に、いくつかのバリエーションを与えるため、0.5 と 1.5 に値を設定してください。これで、パーティクルグラフィックスの繰り返しが、かなり目立たないようになるはずです。

使用方法

テストの間、繰り返し爆発を見ることができるように、Looping プロパティを有効にしておくと便利です。しかし、完成したゲームでは、爆発が 1 度だけ起こるように、これを無効にします。爆発する可能性があるオブジェクト(例えば、燃料タンク)の爆発を設計している場合は、オブジェクトに Particle System コンポーネントを加えて Play On Awake プロパティを無効にしておく場合もあります。それから、必要に応じてスクリプトから爆発をオフに設定することができます。

    void Explode() {
            ParticleSystem exp = GetComponent<ParticleSystem>();
            exp.Play();
            Destroy(gameObject, exp.main.duration);
        }

他のケースでは、爆発は衝撃の時点で起こります。オブジェクトが原因で爆発する場合 (例えば、手榴弾)、時間を遅らせて、あるいは、それがターゲットと接触したときに上記で詳述した Explode 関数を呼び出します。

    // 少し遅れて爆発が発生します。
        public float fuseTime;

        void Start() {
            Invoke("Explode", fuseTime);
        }



        // 当たった瞬間に爆発します。
        void OnCollisionEnter(Collision coll) {
            Explode();
        }

爆発が、実際のゲームにおいて表示されないオブジェクト (例えば、非常に速く移動するミサイル)によって発生する場合は、単に適切な場所で爆発をインスタンス化するだけです。例えば、raycast で接触点を決める場合もあります。

    // 爆発オブジェクトにおいて
        void Start() {
            ParticleSystem exp = GetComponent<ParticleSystem>();
            exp.Play();
            Destroy(gameObject, exp.main.duration);
        }

    
        // 砲弾スクリプト例
        public GameObject explosionPrefab;

        void Update() {
            RaycastHit hit;

            if (Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out hit)) {
                Instantiate (explosionPrefab, hit.point, Quaternion.identity);
            }
        }

その他のアイデア

ここで開発された爆発は非常に基本的なものですが、ゲームに求めているものを忠実に表現するために、さまざまな面を修正できます。

使用するパーティクルグラフィックスは、プレイヤーがどのように爆発を「認識する」 かに大きな影響を及ぼします。たくさんの小さな個々に認識できる炎は、飛び散って燃える火の粉を表します。完全に他と分離した動かない大きなパーティクルは、破壊された燃料タンクから発生する火の玉のように見えます。通常は、効果を完成させるために、一緒にいくつかのプロパティを変更する必要があります。たとえば、火の玉は消滅するまでには長く持続し、さほど拡大することがありません。逆に、密閉された燃料タンクの破裂は、燃焼する破片をかなりの距離まで飛び散らせたりします。

2–3 のプロパティは、ランダムな値に設定されています。しかし、他の多くのプロパティには Random Between Two Constants/Curves オプションがあり、いろいろな方法でバリエーションを追加するためにこれらを使用することができます。パーティクルの繰り返しが目立つのを回避するために、サイズと回転を変えるのも効果がありますが、Start DelayStart LifetimeStart Speed プロパティが少しランダムに動くようにするのも良い方法です。少さな変化は、爆発が制御された機械的なプロセスというよりはむしろ、自然で予測不能であるという印象を強めるのに役立ちます。より大きな変化は、不揃いの爆発を表します。たとえば、Start Delay を変えることで、強く破裂する爆発ではなく、少しゆっくりと飛散する爆発 (多分、車両の燃料タンクに別々に引火していくような) になります。


  • 2017–07–27 修正されたページ

  • GameObject メニューは Unity 4.6 で変更

ビルトインのパーティクルシステムの例
車両からの排気煙の作成