Я борюсь с проблемой загрузки Unity Sprites из SpriteAtlas, загруженной в AssetBundle.
В нашей текущей игре я пытаюсь реализовать AssetBundles, чтобы удалить использование папки «Resources» и уменьшить объем памятинакладные расходы (между прочим).
В приложении 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, текстура настроена правильно.![TestApp - Texture is correctly set](https://i.stack.imgur.com/rhSqH.png)
А вот в GameApp текстура не установлена ![GameApp - Texture is not set](https://i.stack.imgur.com/H0PSm.png)
Вещи, которые я проверял и подтверждал между версиями
- Ни в GameApp, ни в TestApp нет ошибок или исключений.
- Он работает правильно при сборке и развертывании на устройстве (пока тестировалось только на Android)
- Объект-спрайт возвращается в обратном вызове onLoadAction в GameApp.
- Я использую одни и те же AssetBundles и Sprites в обоих приложениях.
- Я провел параллельное сравнение настроек объекта Image в инспекторе в обоих приложениях.
- Оба приложения настроены на одну и ту же платформу сборки (я пробовал Android, WebGL и StandaloneWindows, и у всех одинаковый результат)
- AssetBundles созданы для правильной платформы сборки (как указано выше)
Единственное различие, которое я вижу между TestApp и GameApp, состоит в том, что GameApp намного больше / сложнее, и у него есть изменение сцены (мы начинаем с загрузки сцены дона игровую сцену), но я не понимаю, как что-либо из этого должно повлиять на что-либо.
Я также настроил и протестировал версию, используя AssetBundle.LoadFromFileAsync () и загрузив файл изпапка StreamingAssets, с теми же результатами
Итак, мои вопросы: это ошибка в редакторе Unity?Что я должен смотреть, чтобы попытаться это исправить?Мы не можем использовать AssetBundles, пока я не найду решение.
Я использовал актив AssetBundleBrowser для настройки AssetBundles.
Я тестировал с различными версиями Unity, от более ранних выпусков 2018.1 до последнего выпуска (2018.2.7f1 на момент написания).
(Крест опубликован с Форумы Unity )
--- Обновление ---
Уже упоминалось, что это дублирующий вопрос этот вопрос , однако я задаю совершенно другой вопросвопрос.Мой код работает правильно на устройстве, но не работает в редакторе 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);
}