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

使用Addressable Asset System无法播放AudioClip问题求助

问题分析与解决方案

核心问题:Addressables加载的AudioClip在Use Existing Build模式下,虽能正确获取资源名称,但无法赋值给AudioSource并播放,而Use Asset Database模式正常。结合你的代码和操作,主要原因及解决方法如下:

1. 资源释放时机错误

你在调用PlayVoice后立即执行Addressables.Release(clip),在Use Existing Build模式下,AssetBundle加载的资源会被立即标记为可回收,导致AudioSource无法持有有效资源。

修正方案:
等待音频播放完成后再释放资源,可通过AudioSource的回调或协程实现:

  • 修改PlayVoice方法,添加播放完成回调:
public void PlayVoice(AudioClip clip, float duration = 0.2f, bool loop = false, Action onComplete = null)
{
    Debug.Log(clip.name + " voiceStart");
    VoiceTrack.clip = clip;
    VoiceTrack.loop = loop;
    VoiceTrack.Play();
    VoiceTrack.DOFade(1f, duration);

    // 非循环时,等待播放完成后释放资源
    if (!loop)
    {
        float totalDuration = duration + clip.length;
        VoiceTrack.StartCoroutine(ReleaseAfterPlay(totalDuration, clip, onComplete));
    }
}

private IEnumerator ReleaseAfterPlay(float delay, AudioClip clip, Action onComplete)
{
    yield return new WaitForSeconds(delay);
    Addressables.Release(clip);
    onComplete?.Invoke();
}
  • 调用时调整释放逻辑:
public async UniTask ExecuteAsync(CallInstReference reference, InstRunner runner, CancellationToken cancelToken)
{
    AudioClip clip = await Addressables.LoadAssetAsync<AudioClip>(clipAddress.Get());
    reference.world.callSoundManager.PlayVoice(clip, duration, false);
    // 不再在这里立即Release,交给PlayVoice内部处理
}

2. 确保操作在主线程执行

Unity的组件操作(如AudioSource赋值)必须在主线程完成,UniTask的await可能因调度问题跑到后台线程。

验证与修正:
加载完成后切换到主线程再执行播放逻辑:

public async UniTask ExecuteAsync(CallInstReference reference, InstRunner runner, CancellationToken cancelToken)
{
    AudioClip clip = await Addressables.LoadAssetAsync<AudioClip>(clipAddress.Get());
    await UniTask.SwitchToMainThread(); // 强制切换到主线程
    reference.world.callSoundManager.PlayVoice(clip, duration);
}

3. 检查Addressables构建配置

  • 确认目标AudioClip所在的Group已勾选Include in Build选项,避免构建时被遗漏。
  • 执行彻底清理构建:先选Clean Build > Clear All,再重新执行New Build > Default Build Script,确保旧AssetBundle被完全替换。

4. 追加资源有效性检查

虽然打印了clip.name,但可额外验证资源状态:

public void PlayVoice(AudioClip clip, float duration = 0.2f, bool loop = false)
{
    if (clip == null)
    {
        Debug.LogError("加载的AudioClip为空!");
        return;
    }
    if (!clip.isReadyToPlay)
    {
        Debug.LogError($"AudioClip {clip.name} 未加载完成,无法播放!");
        return;
    }
    // 后续播放逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:40:34