Проблемы с отображением спрайтов, загруженных из AssetBundle в режиме Editor Play - PullRequest
0 голосов
/ 25 сентября 2018

Я борюсь с проблемой загрузки 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

А вот в GameApp текстура не установлена ​​GameApp - Texture is not set

Вещи, которые я проверял и подтверждал между версиями

  • Ни в 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);
}

1 Ответ

0 голосов
/ 15 октября 2018

Оказывается, что проблема была вызвана настройками SpritePacker.

Если я установил режим SpritePacker (в «Правка-> Настройки проекта-> Редактор) на« Включен для сборок », то спрайты не будутне загружается должным образом, в то время как если я установлю его на «Всегда включено» (по умолчанию, я считаю), то спрайты и SpriteAtlas будут загружены правильно из AssetBundle.

(я поднял это как ошибку сЕдинство, но ответа еще не слышали).

...