Unity中如何限制OnParticleCollision仅触发粒子发射器GameObject的回调?
解决方案:避免粒子碰撞双回调问题
一、脚本层面优雅区分(推荐)
Unity默认会在粒子碰撞时,同时通知发射器对象和被碰撞对象触发OnParticleCollision回调。要区分「自身粒子击中他人」和「被他人粒子击中」两种场景,可通过获取碰撞事件所属的粒子系统来判断:
核心逻辑是:用ParticlePhysicsExtensions.GetCollisionEvents方法,检查当前对象的粒子系统是否产生了碰撞事件。若有,则是自身粒子击中目标;反之则是被其他对象的粒子击中。
修改后的代码示例:
using UnityEngine; using System.Collections.Generic; public class ParticleCollisionHandler : MonoBehaviour { private ParticleSystem _ownParticleSystem; private List<ParticleCollisionEvent> _collisionEvents = new List<ParticleCollisionEvent>(); void Awake() { _ownParticleSystem = GetComponent<ParticleSystem>(); } public void OnParticleCollision(GameObject other) { // 获取当前对象粒子系统与other的碰撞事件数量 int eventCount = ParticlePhysicsExtensions.GetCollisionEvents(_ownParticleSystem, other, _collisionEvents); if (eventCount > 0) { // 仅处理自身粒子击中目标的情况 Debug.Log($"The bullet fired by {gameObject.name} hit {other.name}"); } // 若需要处理被击中的逻辑,可在else分支添加代码 // else // { // Debug.Log($"{gameObject.name} was hit by {other.name}'s bullet"); // } } }
这样只有粒子发射器(如Jack)会输出正确的碰撞日志,被碰撞对象(如John)的回调因检测不到自身粒子系统的碰撞事件,会跳过错误输出。
二、配置层面限制回调接收
如果想通过粒子系统配置避免双回调,可按以下操作:
- 选中所有作为被碰撞目标的对象(如John)的Particle System组件
- 在Inspector面板的「Collision」模块中,关闭Send Collision Messages选项
但该方法有局限性:若这些对象本身需要发射粒子并接收自身的碰撞回调,关闭此选项会同时影响它们自身的粒子碰撞逻辑,仅适用于「目标对象从不发射粒子」的场景。
内容的提问来源于stack exchange,提问作者xiaomeng.fan
相关产品推荐
相关产品推荐

