Unity - Particle Systemで衝突した座標を取得する。
Unity - Particle Systemで衝突した座標を取得する。
Particle Systemで発生させた粒子1つ1つにColliderを付け、衝突判定と共に座標を取得する方法を記します。
本記事では動画のものを作ります。このシンプルなものから様々なものに応用させられることを願います。
開発環境
- Unity 2020.1.6f
- Visual Studio Code
- Windows10
では早速始めます。
1. PlaneオブジェクトとParticleオブジェクトをシーンに追加。
Planeでなくてもいいのですが、今回は衝突判定が分かりやすいように、Planeを使用します。
・Hierarchyで右クリック→3D Object>Plane
・Hierarchyで右クリック→Effects>Particle System
こんな感じになると思います。
2. Particle Systemの設定
・Transformの設定
inspectorからParticle Systemの設定をしていきます。
inspectorウィンドウが無い場合は、メニューから→Window>General>Inspectorで表示できます。
RotationのXがデフォルトでは-90となっていますが、こちらはややこしくなる場合が多いので、私はいつもRotationのXを0にします。
上から降らせるイメージなので、PositionのYは10にしておきます。
・Emissionの設定
EmissionはParticleの出現数を設定するパラメーターです。
衝突判定をわかりやすくするためにとりあえず1にしておきます。
プロパティ | 内容 |
---|---|
Rate over Time | ユニットタイム毎に発生する個数。 |
Rate over Distance | ユニット距離毎に発生する個数。 |
・Shapeの設定
ShapeのRotation Xを90にします。これで下に向いたと思います。
Shapeモジュールではプロパティで、発生源の形に関するものを設定することができます。 今回はデフォルトのConeを使います。
Shapeによって発生する角度等も変わってくるので、変更した場合にはRotationで下に向くように設定し直して下さい。
・Rendererの設定
Rendererモジュールでは、Particleのマテリアルやサイズなどを設定できます。
Render ModeをMeshにすると、3DモデルのメッシュデータをParticleの粒として発生させることができます。
ここではデフォルトのBillboardを使用します。
また、デフォルトのサイズではParticleの粒が大きい為、衝突判定をシビアに目視できるようにサイズを0.01と、小さくしておきます。
・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の衝突判定をしてくれます。
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になります。
最後までご覧いただきありがとうございました。
動作確認できましたでしょうか、なにかご不明点ございましたらコメント欄にお書きよせください。