首页 文章

在编辑器播放模式下显示从AssetBundle加载的Sprite的问题

提问于
浏览
1

我正在努力解决Unity中从SpriteAtlas加载Sprites的问题,并在AssetBundle中下载 .

在我们当前的游戏中,我正在尝试实现AssetBundles以删除“资源”文件夹使用情况,并减少内存开销(以及其他内容) .

在游戏应用程序中,下载的精灵使用相同的代码来下载和显示精灵 . 我将从这里开始将这两个版本称为 TestAppGameApp . 重申一下,这个问题只是在编辑器中运行时的问题(不是最终的设备构建),但是这对我们来说是一个游戏破坏者,因为我们根本无法开发和测试应用程序 . 与在编辑器中运行相比,将构建转换为设备的周转时间太长 .

我用于加载资产包的脚本的简化版本如下 . (为了简洁起见,这已被大大简化,包括剥离所有对象缓存和错误处理等)

public IEnumerator GetSpriteFromBundle(string bundleURL, string spriteAtlasName, string spriteName, Action<Sprite> onLoadAction)
{
    //  get the AssetBundle
    AssetBundle bundle = null;
    UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(bundleURL);
    yield return request.SendWebRequest();
    if (!request.isNetworkError && !request.isHttpError)
    {
        bundle = DownloadHandlerAssetBundle.GetContent(request);
    }

    //  Get the SpriteAtlas
    SpriteAtlas atlas = null;
    if (bundle != null)
    {
        if (bundle.Contains(spriteAtlasName))
        {
            AssetBundleRequest assetRequest = bundle.LoadAssetAsync<SpriteAtlas>(spriteAtlasName);
            yield return assetRequest;
            if (assetRequest.isDone)
            {
                atlas = assetRequest.asset as SpriteAtlas;
            }
        }
    }

    //  Get the Sprite
    Sprite sprite = null;
    if (atlas != null)
    {
        sprite = atlas.GetSprite(spriteName);
    }
    onLoadAction(sprite);
}

我用来调用它来加载Sprite的脚本如下所示(再次删除了错误处理):

public void Start()
{
    UnityEngine.UI.Image displayImage = GameObject.Find("Path/To/ImageObject").GetComponent<UnityEngine.UI.Image>();
    StartCoroutine(
         GetSpriteFromBundle(
            "https://mycdn.com/myassetbundles/gamesprites",      // AssetBundleURL
            "GameSprites",          //    SpriteAssetName
            "Icon1",                      //    SpriteName
            (sprite) =>
            {
                displayImage.sprite = sprite;
            })
        );
}

最终的结果是一切都在TestApp中正常工作和加载,但是当在编辑器中播放GameApp时,精灵要么是不可见的,要么显示为带有3个方格的奇怪图像 .

我可以看到的唯一区别是,当我使用框架调试器来查看TestApp和GameApp之间的差异时,TestApp会在批处理中显示SpriteAtlas纹理,但GameApp不会 .

正如您在TestApp中看到的那样,纹理已正确设置 .
TestApp - Texture is correctly set

而在GameApp中,纹理未设置
GameApp - Texture is not set

我在版本之间检查和确认的事情

  • GameApp和TestApp都没有任何错误或例外 .

  • 在构建和部署到设备时它可以正常工作(到目前为止仅在Android上测试过)

  • 精灵对象是在GameApp的onLoadAction回调中返回的 .

  • 我在两个应用程序中使用相同的AssetBundles和Sprites .

  • 我已经在两个应用程序中检查器中的Image对象设置进行了并排比较 .

  • 两个应用程序都设置为相同的构建平台(我尝试过Android,WebGL和StandaloneWindows,并且都具有相同的结果)

  • AssetBundles是为正确的构建平台构建的(如上所述)

我在TestApp和GameApp之间看到的唯一区别是GameApp更大/更复杂,并且它有一个场景变化(我们在进入游戏场景之前从加载场景开始),但我不喜欢看看其中任何一个应该如何影响任何事情 .

我还使用AssetBundle.LoadFromFileAsync()设置并测试了一个版本,并从StreamingAssets文件夹加载文件,结果相同

所以,我的问题:这是Unity编辑器中的错误吗?我该怎么办才能尝试解决这个问题?在找到解决方案之前,我们基本上不能使用AssetBundle .

我已经使用了AssetBundleBrowser资产来设置AssetBundles .

我已经使用各种版本的Unity进行了测试,从早期的2018.1版本到最新版本(编写本文时为2018.2.7f1) .

(Cross发自Unity Forums

---更新---

有人提到这是一个重复的问题this question,但我问的是一个完全不同的问题 . 我的代码在设备上正常运行,但在Unity编辑器中不起作用 .

我也尝试重构我的代码来查询Sprite而不是SpriteAtlas,并使用LoadAssetWithSubAssetsAsync方法,使用以下代码,我仍然有相同的最终结果,在编辑器中没有显示精灵 .

private IEnumerator GetSpriteFromBundle(string bundleURL, string spriteName, Action<Sprite> onLoadAction)
{
    //  get the AssetBundle
    AssetBundle bundle = null;
    UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(bundleURL);
    yield return request.SendWebRequest();
    if (!request.isNetworkError && !request.isHttpError)
    {
        bundle = DownloadHandlerAssetBundle.GetContent(request);
    }

    //  Get the Sprite
    Sprite sprite = null;
    if (bundle != null)
    {
        if (bundle.Contains(spriteName))
        {
            AssetBundleRequest assetRequest = bundle.LoadAssetWithSubAssetsAsync<Sprite>(spriteName);
            yield return assetRequest;
            if (assetRequest.isDone)
            {
                for (int i = 0; i < assetRequest.allAssets.Length; i++)
                {
                    sprite = assetRequest.allAssets[i] as Sprite;
                    if (sprite != null && sprite.name == spriteName)
                    {
                        onLoadAction(sprite);
                        yield break;
                    }
                }
            }
        }
    }
    onLoadAction(null);
}

1 回答

  • 0

    事实证明,问题是由SpritePacker设置引起的 .

    如果我将SpritePacker模式(在Edit-> Project Settings-> Editor中)设置为“Enabled for Builds”,则精灵未正确加载,而如果我将其设置为“Always Enabled”(我相信默认值),那么sprite,SpriteAtlas从AssetBundle正确加载 .

    (我已将此作为Unity的错误提出,但尚未听到回复) .

相关问题