Извлекать изображения асинхронные из URL в unity3d

Я делаю игру, в которой мне нужно интегрировать таблицу лидеров Facebook и приглашение друзей в Facebook, как в метро Surfer. Я использовал официальный Facebook SDK и сделал это. Но подход, которому я придерживаюсь, неэффективен.

Экран приглашения моего друга имеет собственный пользовательский интерфейс, поэтому я не могу использовать всплывающее окно по умолчанию, поставляемое с Facebook SDK. Я получаю список всех друзей из графа API. Он предоставляет мне список всех идентификаторов пользователей. Но мне нужно было, чтобы имя и изображения друзей отображались в списке прокрутки. Я получаю изображения из URL асинхронно, но всякий раз, когда я пытаюсь получить изображение, мой список прокрутки зависает. вот мой код

IEnumerator start ()
    {

        url ="http://profile.ak.fbcdn.net/hprofile-ak-prn2/t5/1116929_100003613987476_290892640_q.jpg";
        WWW www = new WWW(url);
        yield return www;

        var texture = www.texture;
        this.gameObject.GetComponent<UITexture>().mainTexture = texture;



    }

Я использую сопрограммы, но я не знаю, почему мой свиток зависает при прокрутке, если они асинхронные? Код взят здесь. Я проверил Threading, но www нельзя использовать в темах. Я просто хочу сгладить мой скроллвью, который я сделал, используя NGUI SDK во время выборки изображений.

Проблема 1 - Как сделать плавную прокрутку путем асинхронной загрузки изображений одновременно.

Проблема 2 - Я загружаю каждое изображение в UITexture NGUI, которую я создаю во время выполнения. Но если у кого-то 200 или более друзей, то память моего приложения достигает точки апекса и в конечном итоге приложение вылетает. Есть ли другой способ загрузки большого количества изображений, чтобы они занимали разумную память.

Прокрутка работает гладко во время веб-вызова в редакторе, но не на устройстве (iOS). Зачем?

Пожалуйста, ребята, помогите мне сгладить мой вид прокрутки и проблемы с памятью. Любая помощь будет высоко оценена. Спасибо:)

2 ответа

Решение

Это распространенная проблема на устройствах для любого списка, содержащего более 50 элементов с изображениями. Вам нужно контролировать две вещи: инициализацию элементов списка и загрузку ресурсов.

Вам не нужно загружать все сразу и отображать их. Я бы рекомендовал разбить это на три части:

1. Сохраните данные списка друзей

Получить всех друзей пользователя Facebook и сохранить его в списке. Это не включает загрузку изображений профиля, только основную информацию и URL их изображения профиля. Мы загрузим картинку на более позднем этапе.

2. Пункты пула

Не создавайте более трех элементов списка, которые вы можете отобразить в любой момент времени. При прокрутке вы просто будете использовать уже созданные, например, так:

Повторное использование элементов списка при прокрутке

Третий шаг на этом рисунке нужно выполнять только тогда, когда пользователь поднял палец, и у списка достаточно импульса для продолжения прокрутки. В противном случае у вас должно быть достаточно элементов, загруженных в память, чтобы не требовать этого, когда пользователь просто перетаскивает список.

При перемещении элемента списка в конце или в начале (в зависимости от направления прокрутки) вы должны загрузить данные друга. Вы все еще не загружаете фотографии профиля на этом этапе.

3. Очередь запросов изображений

Вы можете использовать метод OnBecameVisible в Unity, чтобы выяснить, когда элемент в данный момент виден. Но, как правило, вам нужен менеджер, который отслеживает, какие элементы видны в данный момент.

Каждый раз, когда список прокрутки не имеет импульса и пользователь не перетаскивает его, вы ставите в очередь запросы на выборку изображений для элементов, которые в данный момент видны. Это должен обрабатывать другой менеджер, который делает следующее:

  • Сохраняет в памяти N самых последних фотографий профиля, чтобы не загружать их каждый раз
  • Проверяет, загружено ли уже изображение, используя LoadFromCacheOrDownload, как предложил Роберто.
  • Удостоверится, что элемент, для которого был сделан запрос, все еще видим перед настройкой текстуры (иначе он сохраняет изображение в памяти)

Конечно, это очень высокий уровень. Здесь можно реализовать много вещей и разными способами. Но я надеюсь, что вы поняли идею.

Я думал об этом, когда спросил о запуске множества сопрограмм одновременно. Ну, вы просто не можете загрузить их все одновременно и ожидать, что приложение будет работать гладко, аппаратное обеспечение просто не в состоянии справиться с этим.

Вы можете сделать загрузочный экран или что-то подобное, где пользователю придется ждать, чтобы увидеть / использовать скроллер (хотя я никогда не видел игру, делающую это для загрузки картинок на Facebook), или вам придется отказаться от показа их всех в в то же время и создайте пул из небольшого числа WWW-соединений, которые вы можете использовать одновременно, то есть ограничить количество загружаемых изображений одновременно и начинать загрузку нового изображения только после его завершения.

Теперь одна вещь, которая может ускорить процесс - не в первый раз, когда вы запускаете его, а в последующих запусках - это использовать WWW.LoadFromCacheOrDownload() вместо new WWW(), Этот метод будет хранить картинки, которые были загружены в прошлом, и загружать их вместо повторной загрузки. Вот как каждая игра Unity, которую я когда-либо видел, интегрируется с Facebook.

Другие вопросы по тегам