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

Unity Addressables场景下载中已下载场景出现粉色精灵问题求助

问题描述

我有多个可通过Addressables下载的场景,场景下载完成后加载正常,但只要有任意场景处于下载进程中,其他已下载的场景就会出现粉色精灵(Shader丢失的典型表现)。该问题仅出现在Android构建版本中。

注:释放AsyncOperationHandle时会触发问题,但不释放该Handle则无法将场景加载到内存中。我推测可能和Addressables未加载内置Shader有关,但没找到解决办法。

相关代码实现
public class AddreasableSceneThumbnail : MonoBehaviour
{
    [SerializeField] string sceneAddress;
    [SerializeField] Transform downloadProgressUI;
    bool isDownloadStarted;
    bool isDownloaded;
    IEnumerator downloadCour;

    private void Start()
    {
        StartCoroutine(CheckDownload());
    }
    private void OnDestroy()
    {
        if(downloadCour != null)
            StopCoroutine(downloadCour);
        if (downloadHandlerCheck.IsValid())
        {
            Addressables.Release(downloadHandlerCheck);
        }
        if (downloadHandlerDownload.IsValid())
        {
            Addressables.Release(downloadHandlerDownload); 
        }
    }
    AsyncOperationHandle<long> downloadHandlerCheck;
    IEnumerator CheckDownload()
    {
        downloadHandlerCheck = Addressables.GetDownloadSizeAsync(sceneAddress);

        while (!downloadHandlerCheck.IsDone && downloadHandlerCheck.Status !=AsyncOperationStatus.Failed)
        {
            yield return null;
        }

        if (downloadHandlerCheck.Result == 0)
        {
            ActivateButton();
            isDownloaded = true;
        }
        Addressables.Release(downloadHandlerCheck);
    }
    public void OnThumbNailClicked()
    {
        if(isDownloaded)
            Addressables.LoadSceneAsync(sceneAddress,LoadSceneMode.Single);
        if (isDownloadStarted) return;
        isDownloadStarted = true;
        downloadCour= DownloadScene();
        StartCoroutine(downloadCour);
    }
    AsyncOperationHandle downloadHandlerDownload;
    IEnumerator DownloadScene()
    {
        downloadProgressUI.transform.localScale = Vector3.one;
        downloadProgressUI.gameObject.SetActive(true);

        downloadHandlerDownload = Addressables.DownloadDependenciesAsync(sceneAddress);
        while (!downloadHandlerDownload.IsDone)
        {
            downloadProgressUI.localScale = new Vector3(1, 1 - downloadHandlerDownload.PercentComplete, 1);
            yield return null;
        }
        isDownloaded = true;
        ActivateButton();
        Addressables.Release(downloadHandlerDownload); // this is culprit

    }
    public void ActivateButton()
    {
        downloadProgressUI.gameObject.SetActive(false);
    }
}
解决方案

针对Android平台的这个问题,可尝试以下几种修复思路:

1. 预加载内置核心Shader

粉色精灵本质是Shader丢失,Android平台下Addressables下载过程中可能意外释放了共享的内置Shader资源。可以将常用的内置Shader(如Standard、UI/Default等)打包进主包,或者通过Addressables标记为Local资源提前加载:

  • 在Project窗口找到内置Shader(路径:Assets/Resources/UnityShaders或通过Package Manager查看)
  • 将这些Shader添加到Addressables组,设置Load Type为Preload,Location为Local
  • 在游戏启动时调用Addressables.LoadAssetsAsync<Shader>(new List<string>{"Shader地址1", "Shader地址2"}, null)预加载,加载完成后无需释放(因为是本地预加载资源)

2. 延迟释放下载Handle

问题出在释放downloadHandlerDownload时,可改为在场景加载完成后再释放该Handle,避免提前释放导致依赖资源被回收:

IEnumerator DownloadScene()
{
    downloadProgressUI.transform.localScale = Vector3.one;
    downloadProgressUI.gameObject.SetActive(true);

    downloadHandlerDownload = Addressables.DownloadDependenciesAsync(sceneAddress);
    while (!downloadHandlerDownload.IsDone)
    {
        downloadProgressUI.localScale = new Vector3(1, 1 - downloadHandlerDownload.PercentComplete, 1);
        yield return null;
    }
    isDownloaded = true;
    ActivateButton();
    // 暂时不释放,等场景加载完成后再处理
}

// 修改OnThumbNailClicked中的场景加载逻辑
public void OnThumbNailClicked()
{
    if(isDownloaded)
    {
        var loadHandle = Addressables.LoadSceneAsync(sceneAddress, LoadSceneMode.Single);
        StartCoroutine(WaitForLoadAndRelease(loadHandle));
    }
    if (isDownloadStarted) return;
    isDownloadStarted = true;
    downloadCour= DownloadScene();
    StartCoroutine(downloadCour);
}

IEnumerator WaitForLoadAndRelease(AsyncOperationHandle<SceneInstance> loadHandle)
{
    yield return loadHandle;
    if (loadHandle.Status == AsyncOperationStatus.Succeeded)
    {
        // 场景加载完成后再释放下载Handle
        if (downloadHandlerDownload.IsValid())
        {
            Addressables.Release(downloadHandlerDownload);
            downloadHandlerDownload = default;
        }
    }
}

3. 调整资源自动回收设置

在Addressables设置中(Window > Asset Management > Addressables > Groups),找到Advanced Settings,将Resource Manager Settings里的Auto Release相关选项暂时关闭,或者调整回收延迟时间,避免在下载过程中误回收已加载的共享资源。

4. 检查场景依赖的Shader打包情况

确保所有场景中使用的Shader都被正确包含在Addressables的依赖项中:

  • 选中目标场景,在Addressables组中查看其依赖项,确认Shader都被正确标记
  • 如果有Shader未被自动添加,手动将其加入对应Addressables组,避免下载时遗漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:20:15