You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity粒子系统Trigger模块如何获取碰撞目标?

Unity粒子穿透敌人并造成伤害的实现方案

针对你遇到的问题,直接给你两个落地的解决方法,不用射线也不用子弹对象:

方案一:用Collision模块实现穿透+碰撞检测(推荐)

这个方法能直接解决你说的「粒子碰撞后飞散」和「拿不到碰撞目标」的问题:

  1. 选中粒子系统,在Inspector里开启Collision模块
  2. 模块内关键设置:
    • Collision Response:设为None(核心!这样粒子碰撞后不会反弹/减速,直接穿透)
    • Layer Mask:只勾选敌人所在的Layer,避免检测场景中其他无关对象
    • 勾选Send Collision Messages(必须勾,否则不会触发脚本回调)
  3. 给粒子系统挂一个自定义脚本,实现碰撞回调:
    public class ParticleDamage : MonoBehaviour
    {
        public int damage = 10;
        public GameObject attacker; // 绑定攻击者对象,用来传递信息
    
        private void OnParticleCollision(GameObject other)
        {
            // 检测碰撞对象是否是敌人(假设敌人有EnemyHealth脚本)
            EnemyHealth enemyHealth = other.GetComponent<EnemyHealth>();
            if (enemyHealth != null)
            {
                // 给敌人造成伤害,同时传递攻击者信息
                enemyHealth.TakeDamage(damage, attacker);
                // 这里可以自由获取各方信息:
                // 粒子信息:GetComponent<ParticleSystem>()
                // 攻击者信息:attacker.GetComponent<Attacker>()
                // 受害者信息:enemyHealth.GetComponent<Enemy>()
            }
        }
    }
    

这样粒子穿透敌人时,每帧都会触发OnParticleCollision,参数other就是被击中的怪物,同时粒子不会有任何飞散的表现。

方案二:用Trigger模块+IParticleTriggerCallback接口

如果你更倾向用Trigger模块,解决「拿不到碰撞目标」的问题需要实现官方的回调接口:

  1. 开启粒子系统的Trigger模块,设置Layer Mask为敌人Layer
  2. 写一个脚本实现IParticleTriggerCallback接口,挂在粒子系统上:
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ParticleTriggerDamage : MonoBehaviour, IParticleTriggerCallback
    {
        public int damage = 10;
        public GameObject attacker;
    
        public void OnParticleTrigger()
        {
            List<ParticleSystem.Particle> enterParticles = new List<ParticleSystem.Particle>();
            List<GameObject> hitTargets = new List<GameObject>();
    
            // 获取进入Trigger范围的粒子和对应的碰撞对象
            ParticleSystem ps = GetComponent<ParticleSystem>();
            ps.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, enterParticles, hitTargets);
    
            foreach (GameObject target in hitTargets)
            {
                EnemyHealth enemyHealth = target.GetComponent<EnemyHealth>();
                if (enemyHealth != null)
                {
                    enemyHealth.TakeDamage(damage, attacker);
                }
            }
    
            // 必须调用此方法重置Trigger状态,否则会重复触发
            ps.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, enterParticles);
        }
    }
    

这个方法会在粒子进入敌人Collider范围时触发回调,通过hitTargets直接拿到被碰撞的怪物对象。

关于你尝试的「生成临时Trigger盒子」的方法

这个思路是可行的,但需要额外处理:

  • 要给临时盒子加一个脚本,检测进入的粒子(用OnTriggerEnter)
  • 还要加逻辑避免同一敌人在0.1秒内被重复检测(比如用HashSet记录已命中的敌人ID)
  • 相比上面两种方法,多了对象生成/销毁的开销,不如直接用粒子自带的回调高效

内容的提问来源于stack exchange,提问作者Acid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:27:45