我在Unity中从SpriteAtlas加载Sprites时遇到了问题,该资源已从AssetBundle下载。
在我们当前的游戏中,我试图实现AssetBundles来删除“资源”文件夹的使用,并减少内存开销(除其他外)。
在Game应用程序中,下载的精灵在编辑器中运行时无法正确呈现,因此我构建了一个小型测试项目以更好地理解问题。不幸的是,即使我使用相同的代码来下载和显示精灵,测试项目也能完美地工作。从现在开始,我将这两个版本称为 TestApp 和 GameApp 。重申一下,这个问题只是在编辑器中运行时的问题(不是最终的设备版本),但这对我们来说是一个突破,因为我们根本无法开发和测试应用程序。与在编辑器中运行相比,构建设备所需的周转时间太长了。
我用于加载资产捆绑包的脚本的简化版本如下。 (为简洁起见,已对其进行了极大简化,包括剥离所有对象缓存和错误处理等)
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中看到的那样,正确设置了Texture。
我在版本之间检查并确认的内容
我能看到的TestApp和GameApp之间的唯一区别是GameApp更大/更复杂,而且它的场景有所变化(我们从加载场景开始,然后进入游戏内场景),但我看不出这两个都应该如何影响。
我还使用AssetBundle.LoadFromFileAsync()设置并测试了一个版本,并从StreamingAssets文件夹加载文件,结果相同
所以,我的问题是: 这是Unity编辑器中的错误吗?我应该看什么才能尝试解决此问题?在找到解决方案之前,我们基本上无法使用AssetBundles。
我已经使用AssetBundleBrowser资产来设置AssetBundle。
我已经测试了Unity的各种版本,从较旧的2018.1版本到最新版本(在撰写本文时为2018.2.7f1)。
(从Unity Forums发来的十字架)
---更新---
有人提到这是一个重复的问题this question,但是我要问一个完全不同的问题。 我的代码在设备上可以正常工作,但在Unity Editor中不能工作。
我还尝试重组代码以查询Sprite而不是SpriteAtlas,并使用LoadAssetWithSubAssetsAsync方法和以下代码,但最终结果仍然相同,即在编辑器中未显示任何Sprite。 / p>
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);
}
答案 0 :(得分:0)
事实证明,问题是由SpritePacker设置引起的。
如果我将SpritePacker模式(在“编辑”->“项目设置”->“编辑器”中)设置为“为构建启用”,则不会正确加载该精灵,而如果将其设置为“始终启用”(我相信默认设置) ),然后是精灵,然后从AssetBundle中正确加载了SpriteAtlas。
(我将其作为Unity的一个bug提出,但尚未听到回应)。