本日は Unity の技術調査枠です。
Particleのアタリ判定を設定してヒット位置を取得する方法を記事にします。
Particleでアタリ判定を行う
Particle にアタリ判定を付与するには Collision モジュールの設定項目を有効化します。
[Particle System]コンポーネントの[Collision]にチェックを入れ、[Type]を[World]に設定します。
これで Particle が Collider にヒットして跳ね返るようになります。
また今回はヒット位置を取得したいので、ヒット時の通知を行う[Send Collision Message]をチェックしておきます。
その他、[Dampen]でパーティクルの減速、[Lifetime Loss]で跳ね返りパーティクルの削除を設定しました。
今回は利用しませんでしたが[Collider Force]に 0 より大きい値を設定すると、Particle で衝突対象に力を加えることもできます。
docs.unity3d.com
なお、これらのアタリ判定は[Sub Emitters]で生成される子要素の Particle には反映されません。
ヒット位置を取得する
Collision モジュールの[Send Collision Message]をチェックすると、衝突した Particle のオブジェクトと Collider オブジェクトの両方で OnParticleCollision 関数が呼び出されるようになります。
しかし、OnParticleCollision 関数はヒットしたオブジェクトの情報のみを通知します。
docs.unity3d.com
正確なヒット位置を取得するには ParticleSystem から ParticleCollisionEvent のリストを取得する必要があります。
docs.unity3d.com
サンプルコード
サンプルコードとして以下のスクリプトを作成しました。
OnParticleCollision 関数を受け取ると、Particle が対象オブジェクトに衝突した位置を UnityEvent で通知します。
・ParticleCollisionNotice.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events; using System; public class ParticleCollisionNotice : MonoBehaviour { [Serializable] private class VectorUnityEvent : UnityEvent<Vector3> { } private ParticleSystem p_RefParticle; private List<ParticleCollisionEvent> p_CollisionEventList; [SerializeField, Tooltip("ヒット位置の通知")] private VectorUnityEvent p_HitPositionNotice; private void Start() { p_RefParticle = this.GetComponent<ParticleSystem>(); p_CollisionEventList = new List<ParticleCollisionEvent>(); } private void OnParticleCollision(GameObject hitObject) { // パーティクルのヒット位置を取得するため、イベントリストを取得する p_RefParticle.GetCollisionEvents(hitObject, p_CollisionEventList); foreach (ParticleCollisionEvent collisionEvent in p_CollisionEventList) { Vector3 pos = collisionEvent.intersection; Debug.Log("Particle Hit : object name = " + hitObject.name + ", position = " + pos.ToString()); // イベントが登録されていればヒット位置を通知する p_HitPositionNotice?.Invoke(pos); // 今回は1つ目のヒット情報のみ処理する break; } } }
今回のスクリプトは Particle System コンポーネントのオブジェクトにスクリプトを設定しました。
ヒット対象のオブジェクトで OnParticleCollision 関数を受け取る場合は hitObject に ParticleSystem のオブジェクトが返ります。
このため、上記のスクリプトはヒット対象のオブジェクトに設定しても正常に動作しないことに注意が必要です。