Извлекать изображения асинхронные из 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.