Узнать, когда все файлы из массива будут асинхронно загружен

Программирование на Юнити.

Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение Инженер 19 июн 2020, 18:26

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

Так как количество префабов может исчисляться тысячами и все должно работать в рантайме (динамически загружаемые чанки мира), желательно делать это как можно дешевле:
-не прибегать к отдельной корутине для загрузки каждого элемента массива. Так как получатся тысячи корутин.
-не проверять в повторном цикле состояние КАЖДОГО элемент массива, так как даже из-за одного не успевшего загрузиться префаба, придется впустую бегать по всему массиву каждый кадр, пока этот префаб наконец не загрузится.



Синтаксис:
Используется csharp
public IEnumerator<float> PreloadResources(Chunk chunk)
{
        for (int i = 0; i < chunk.entitiesSerialized.Length; i++)
        {
                ushort prefabID = chunk.entitiesSerialized[i].prefabID;
                poolsDictionary[prefabID].resourceRequest = Resources.LoadAsync(prefabID.ToString(), typeof(GameObject));
        }

        if (ЧТО-ТО ОСТАЛОСЬ НЕ ЗАГРУЖЕННЫМ - КАК УЗНАТЬ?)
        {
                yield return Timing.WaitForOneFrame;
        }

        ДЕЛАЕМ ЧТО-ТО ДАЛЕЕ
}


Вот примерный набросок кода. Корутина загружает файлы префабов в память, доступ к файлам по prefabID, скрытым в chunk.entitiesSerialized. И сохраняет ResourceRequest в пул объектов. На самом деле, я могу сохранять в пул Object. Мне это нужно, чтобы повторно не вызывать Resources.LoadAsync, а инстансить объекты уже из кэша в синхронном режиме.

Единственное, что мне нужно- наименее накладным способом определить момент, когда все префабы в корутине будут загружены.
Инженер
UNIт
 
Сообщения: 88
Зарегистрирован: 22 май 2016, 11:13

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение 1max1 19 июн 2020, 19:42

-не проверять в повторном цикле состояние КАЖДОГО элемент массива, так как даже из-за одного не успевшего загрузиться префаба, придется впустую бегать по всему массиву каждый кадр, пока этот префаб наконец не загрузится.

Всё же придется.

Синтаксис:
Используется csharp
    public IEnumerator<float> PreloadResources(Chunk chunk)
    {
        List<ResourceRequest> temp = new List<ResourceRequest>();

        for (int i = 0; i < chunk.entitiesSerialized.Length; i++)
        {
            ushort prefabID = chunk.entitiesSerialized[i].prefabID;

            poolsDictionary[prefabID].resourceRequest = Resources.LoadAsync(prefabID.ToString(), typeof(GameObject));
     
            temp.Add(poolsDictionary[prefabID].resourceRequest);
        }

        while (temp.Count != 0)
        {
            for (int i = 0; i < temp.Count; i++)
            {
                if (temp[i].isDone)
                    temp.RemoveAt(i--);
            }

            yield return Timing.WaitForOneFrame;
        }

        // Всё загружено...
    }
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение Tolking 19 июн 2020, 20:33

Есть причина все усложнять?

public IEnumerator<float> PreloadResources(Chunk chunk)
{
for (int i = 0; i < chunk.entitiesSerialized.Length; i++)
{
ushort prefabID = chunk.entitiesSerialized[i].prefabID;
resourceRequest = Resources.LoadAsync(prefabID.ToString(), typeof(GameObject));

While( !resourceRequest.isDone) yeld return null;
}
}
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2716
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение 1max1 19 июн 2020, 21:03

В таком варианте загрузка последовательная.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5505
Зарегистрирован: 28 июн 2017, 10:51

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение Tolking 19 июн 2020, 21:33

И что? Вы надеетесь, что если запустить считывание с диска 100 файлов параллельно - будет быстрее, чем последовательно считать эти файлы? Не будет. У диска одна головка и время перехода с одной позиции на другую есть...
Ковчег построил любитель, профессионалы построили Титаник.
Аватара пользователя
Tolking
Адепт
 
Сообщения: 2716
Зарегистрирован: 08 июн 2009, 18:22
Откуда: Тула

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение Alex5 19 июн 2020, 21:43

Кроме "головок" есть ещё и кеширование. Или вообще всё это на SSD. Проверять надо, сравнивать.
P.S. да и что есть "головка"? Даже во времена HDD были блоки головок, которые вполне могли считывать с нескольких блинов одновременно. Да, для пользователя это было не заметно, но это было.
Даже были диски (я сам их в руках не держал к сожалению) с двумя блоками головок. Хотя, возможно, это и осталось концептом, но сделать такое проблем точно не представляло.
Linux это просто
Экономика это просто
Forex это просто
Мой канал на YouTube
Аватара пользователя
Alex5
Старожил
 
Сообщения: 507
Зарегистрирован: 22 авг 2019, 17:37

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение seaman 20 июн 2020, 13:39

Не забывайте, что в билде "папка" ресурсов - это не папка, а архив (ну или несколько архивов, если данных очень много).
При первом же чтении он скорее всего закешируется и остальные ресурсы из него будут добываться быстрее...
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение Jarico 21 июн 2020, 13:34

Alex5 писал(а):Кроме "головок" есть ещё и кеширование. Или вообще всё это на SSD. Проверять надо, сравнивать.
P.S. да и что есть "головка"? Даже во времена HDD были блоки головок, которые вполне могли считывать с нескольких блинов одновременно. Да, для пользователя это было не заметно, но это было.
Даже были диски (я сам их в руках не держал к сожалению) с двумя блоками головок. Хотя, возможно, это и осталось концептом, но сделать такое проблем точно не представляло.


Ну так речь идёт о не аппаратном обеспечении...

Двиг так устроен что он при запуске игры кэширует все ресурсы из архивов (обычно кэшируются архивы имеющие отношение к первой сцене), а затем после загрузки другой сцены загружаются зависимости для запущенных сцен

К примеру загрузили сцену sample1, загрузились зависимости для неё и выгрузились зависимости для предыдущей
Github: _https://github.com/redheadgektor
Discord: Конь! Чаю!#9382 (сижу редко)
YouTube: _https://www.youtube.com/channel/UCPQ04Xpbbw2uGc1gsZtO3HQ
Telegram: _https://t.me/redheadgektor
Аватара пользователя
Jarico
Адепт
 
Сообщения: 1084
Зарегистрирован: 06 янв 2019, 17:37
Откуда: 0xDEAD
Skype: none
  • Сайт

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение Alex5 21 июн 2020, 13:45

Jarico писал(а):Ну так речь идёт о не аппаратном обеспечении...

Я в курсе. :) Я говорил всего лишь о том, что в современном мире далеко не факт, что "параллельное" будет быстрее "последовательного". Могут быть накладные расходы. Не чистая "гонка" конечно. Проверять надо.
Linux это просто
Экономика это просто
Forex это просто
Мой канал на YouTube
Аватара пользователя
Alex5
Старожил
 
Сообщения: 507
Зарегистрирован: 22 авг 2019, 17:37

Re: Узнать, когда все файлы из массива будут асинхронно загружен

Сообщение Iq51 22 июн 2020, 10:42

Синтаксис:
Используется csharp
public IEnumerator<float> PreloadResources(Chunk chunk)
{
        var unloadedCount  = chunk.entitiesSerialized.Length;
        for (int i = 0; i < chunk.entitiesSerialized.Length; i++)
        {
                ushort prefabID = chunk.entitiesSerialized[i].prefabID;
                Resources.LoadAsync<GameObject>(prefabID.ToString()).completed += asyncOperation =>
                {
                       unloadedCount--;
                       var request = asyncOperation as ResourceRequest;                      
                       Debug.Log($"{request.asset.name} LOADED");
                };
        }
        while (unloadedCount > 0)
        {
                yield return Timing.WaitForOneFrame;
        }
        ДЕЛАЕМ ЧТО-ТО ДАЛЕЕ
}
Iq51
UNIт
 
Сообщения: 64
Зарегистрирован: 19 окт 2011, 02:34


Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 14