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

Unity粒子金币收集系统:单粒子重复收集问题求助

问题分析与解决方案

问题核心:同一金币粒子被重复触发Enter事件,导致单粒子多次计入金币计数。原因是设置粒子remainingLifetime = 0后,粒子不会立即被销毁,需等到粒子系统下一次更新才会移除,期间粒子若仍处于玩家碰撞体内,会被重复检测为进入事件。


修复步骤

1. 配置粒子系统自定义数据

选中金币粒子预制体的ParticleSystem组件,添加Custom Data模块:

  • 启用Float通道(选择Element 0)
  • 设置初始值为0(代表未收集状态)

2. 修改CoinParticle脚本

更新OnParticleTrigger方法,通过自定义数据标记已收集的粒子,避免重复计数:

private void OnParticleTrigger()
{
    int triggeredParticles = ps.GetTriggerParticles(ParticleSystemTriggerEventType.Enter, particles);

    for (int i = 0; i < triggeredParticles; i++)
    {
        ParticleSystem.Particle p = particles[i];
        
        // 检查粒子是否已被收集
        float isCollected = p.GetCustomData(0);
        if (isCollected >= 1f)
        {
            continue;
        }

        p.remainingLifetime = 0f;
        p.SetCustomData(0, 1f); // 标记为已收集
        controller.goldAmount++;
        
        particles[i] = p;
    }

    ps.SetTriggerParticles(ParticleSystemTriggerEventType.Enter, particles);
}

3. 额外优化(可选)

  • 避免在Awake中使用FindAnyObjectByType,改为通过Inspector面板直接赋值玩家引用,减少性能开销
  • 添加自动销毁逻辑,粒子全部消失后销毁金币粒子对象:
private IEnumerator DestroyAfterParticles()
{
    yield return new WaitUntil(() => !ps.isPlaying && ps.particleCount == 0);
    Destroy(gameObject);
}

public void dropCoins(Vector2Int coinDropRange)
{
    ParticleSystem.Burst burst = new ParticleSystem.Burst(0.0f, (short)coinDropRange.x, (short)coinDropRange.y, 0.01f);
    ps.emission.SetBursts(new ParticleSystem.Burst[] { burst });
    ps.Play();
    StartCoroutine(DestroyAfterParticles());
}

4. 检查粒子系统Trigger设置

  • 仅勾选Enter事件,取消Stay/Exit的勾选(除非有特殊需求)
  • 确认触发碰撞体绑定的是玩家的主碰撞体(如胶囊碰撞体),而非子对象的冗余碰撞体

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:52:08