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

Unity中GameObject最后一次受击销毁时伤害音效无法播放问题求助

问题根因

你的推测完全正确,最后一次击打音效无法播放是因为:PlayOneShot触发后,下一帧Update检测到healthAmount <= 0就直接销毁了当前GameObject,挂载在该对象上的AudioSource也会同步被销毁,还没播放完的音效直接被中断。
Debug.Log能正常输出是因为日志是在OnTriggerEnter触发时同步执行的,早于对象销毁的时机。

可行解决方案

方案1:延迟销毁对象(改动最小)

给Destroy方法添加第二个参数,设置延迟销毁的时长为音效的时长,等音效播放完成后再销毁对象:

private void Update()
{
    if(healthAmount <= 0)
    {
        // 先关闭碰撞体,避免延迟销毁期间被再次触发击打逻辑
        GetComponent<Collider2D>().enabled = false;
        // 延迟音效时长后销毁对象
        Destroy(gameObject, clip.length);
    }
}

如果你的对象还有其他生效逻辑,可以额外加一行gameObject.SetActive(false),只保留AudioSource生效播完音效。

方案2:使用不依赖当前对象的静态方法播放音效

直接调用Unity提供的AudioSource.PlayClipAtPoint静态方法,该方法会在指定位置生成临时的AudioSource,播放完成后自动销毁,完全不受当前对象销毁的影响:
修改TakeDamage方法内的播放逻辑即可:

public void TakeDamage(float Damage)
{
    // 替换原来的source.PlayOneShot(clip)
    AudioSource.PlayClipAtPoint(clip, transform.position);
    healthAmount -= Damage;
    healthBar.fillAmount = healthAmount / 100;
}

这个方案不需要修改销毁逻辑,适合不需要统一管理音效的场景。

方案3:全局音效管理器播放

如果项目有统一的音效管理需求,可以把AudioSource挂载到全局不会被销毁的管理类对象上,所有受击音效都调用管理类的接口播放,也不会受目标对象销毁的影响。

额外注意

你当前代码里OnTriggerEnter2D中加了!source.isPlaying的判断,会导致前一次受击音效还没播放完时,新的击打不会触发伤害和音效,如果这不是你预期的逻辑,可以按需移除该判断。

内容的提问来源于stack exchange,提问作者lapezi prod.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:06:04