Buchi.com

メディアアートのエンジニアが気ままに残していきます。

Unity - Particle Systemで衝突した座標を取得する。

Unity - Particle Systemで衝突した座標を取得する。

Particle Systemで発生させた粒子1つ1つにColliderを付け、衝突判定と共に座標を取得する方法を記します。

本記事では動画のものを作ります。このシンプルなものから様々なものに応用させられることを願います。

youtu.be

開発環境

では早速始めます。

1. PlaneオブジェクトとParticleオブジェクトをシーンに追加。

Planeでなくてもいいのですが、今回は衝突判定が分かりやすいように、Planeを使用します。

・Hierarchyで右クリック→3D Object>Plane

・Hierarchyで右クリック→Effects>Particle System

unityのparticle systemの画像
画像01: PlaneオブジェクトとParticle SystemオブジェクトをHierarchyに追加。
  こんな感じになると思います。

2. Particle Systemの設定

・Transformの設定

inspectorからParticle Systemの設定をしていきます。

inspectorウィンドウが無い場合は、メニューから→Window>General>Inspectorで表示できます。

RotationのXがデフォルトでは-90となっていますが、こちらはややこしくなる場合が多いので、私はいつもRotationのXを0にします。

上から降らせるイメージなので、PositionのYは10にしておきます。

unityのparticle systemのtransformに関する画像。
画像02: Particle Systemの設定。

・Emissionの設定

EmissionはParticleの出現数を設定するパラメーターです。

衝突判定をわかりやすくするためにとりあえず1にしておきます。

プロパティ 内容
Rate over Time ユニットタイム毎に発生する個数。
Rate over Distance ユニット距離毎に発生する個数。

unityのparticle systemのEmissionに関する画像。
画像03: Emissionの設定。
 

・Shapeの設定

ShapeのRotation Xを90にします。これで下に向いたと思います。

Shapeモジュールではプロパティで、発生源の形に関するものを設定することができます。 今回はデフォルトのConeを使います。

Shapeによって発生する角度等も変わってくるので、変更した場合にはRotationで下に向くように設定し直して下さい。

unityのparticle systemのshapeに関する画像。
画像04: Shapeの設定。
 

・Rendererの設定

Rendererモジュールでは、Particleのマテリアルやサイズなどを設定できます。

Render ModeをMeshにすると、3DモデルのメッシュデータをParticleの粒として発生させることができます。

ここではデフォルトのBillboardを使用します。

また、デフォルトのサイズではParticleの粒が大きい為、衝突判定をシビアに目視できるようにサイズを0.01と、小さくしておきます。

unityのparticle systemのRendererに関する画像。
画像05: Rendererの設定。

・Collisionの設定

プロパティ 変更点
Type Plane
Max Kill Speed 1
Radius Scale 0.01
Send Collision Messages チェックを入れる
Visualize Bounds チェックを入れる
  • Type: Planeに変更。worldにすると全てに衝突判定を返します。Particle同士の衝突も起こり得るのでPlaneにします。 他にもtag機能を使うことでParticle同士の衝突を回避できます。

  • Max Kill Speed: Colliderに当たった時にこの値よりスピードが大きいものを消滅させます。今回は1にしておくことで、全てのParticleを消滅させます。

  • Radius Scale: 0.01に変更→rendererで設定したサイズとColliderのサイズを合わせる為。

  • Send Collision Messages: チェックを入れます。これは後ほどスクリプトで受け取れるようにする為です。 OnParticleCollision関数で取得できます。

  • Visualize Bounds: Colliderを可視化します。まあ、サイズが0.01なので今回はほぼ見えません。

  • Planesプロパティの右側をクリックすると画像06のようなウィンドウが表示されます。Sceneタブに切り替えて、Planeを選択します。 こうすることで、最初に配置したPlaneとParticleの衝突判定をしてくれます。

unityのparticle systemのCollisionに関する画像。
画像06: Collisionの設定。

3. Scriptを書く。

ProjectのAsset下で右クリック→Create>C#Sctipt

名前はParticleCollisionとしました。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ParticleCollision : MonoBehaviour
{
    private ParticleSystem particle;
    private List<ParticleCollisionEvent> collisionEventList;

    public GameObject objprefab;

    void Start()
    {
        particle = GetComponent<ParticleSystem>();
        collisionEventList = new List<ParticleCollisionEvent>();
    }

    void OnParticleCollision(GameObject obj)
    {
        particle.GetCollisionEvents(obj, collisionEventList);
        foreach(var collisionEvent in collisionEventList)
        {
            Vector3 pos = collisionEvent.intersection;
            Instantiate<GameObject>(objprefab, pos, Quaternion.identity);
        }
    }
}

これをParticle Systemオブジェクトに加えます。ドラッグアンドドロップもしくは、Particle Systemを選択した状態で、InspectorよりAdd Component>ParticleCollisionを選択でできます。

Objprefabに何かしらのprefabをドラッグアンドドロップで追加して、実行します。

今回は適当にCube(Scale(X, Y, Z) = 0.3, 0.3, 0.3)のPrefabを作り、使用しました。

Prefabの作り方は、Hierarchyで右クリック→3D Object>Cubeを選択

Positionが0,0,0になっていることを確認し、Scaleを0.3, 0.3, 0.3にしたらProjectへドラッグアンドドロップ

最後にHierarchyに残っているCubeを削除したらProjectにあるものがPrefabになります。

youtu.be

最後までご覧いただきありがとうございました。

動作確認できましたでしょうか、なにかご不明点ございましたらコメント欄にお書きよせください。