Страница 1 из 1

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

СообщениеДобавлено: 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, а инстансить объекты уже из кэша в синхронном режиме.

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

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

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

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

Синтаксис:
Используется 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;
        }

        // Всё загружено...
    }

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

СообщениеДобавлено: 19 июн 2020, 20:33
Tolking
Есть причина все усложнять?

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;
}
}

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

СообщениеДобавлено: 19 июн 2020, 21:03
1max1
В таком варианте загрузка последовательная.

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

СообщениеДобавлено: 19 июн 2020, 21:33
Tolking
И что? Вы надеетесь, что если запустить считывание с диска 100 файлов параллельно - будет быстрее, чем последовательно считать эти файлы? Не будет. У диска одна головка и время перехода с одной позиции на другую есть...

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

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

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

СообщениеДобавлено: 20 июн 2020, 13:39
seaman
Не забывайте, что в билде "папка" ресурсов - это не папка, а архив (ну или несколько архивов, если данных очень много).
При первом же чтении он скорее всего закешируется и остальные ресурсы из него будут добываться быстрее...

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

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


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

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

К примеру загрузили сцену sample1, загрузились зависимости для неё и выгрузились зависимости для предыдущей

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

СообщениеДобавлено: 21 июн 2020, 13:45
Alex5
Jarico писал(а):Ну так речь идёт о не аппаратном обеспечении...

Я в курсе. :) Я говорил всего лишь о том, что в современном мире далеко не факт, что "параллельное" будет быстрее "последовательного". Могут быть накладные расходы. Не чистая "гонка" конечно. Проверять надо.

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

СообщениеДобавлено: 22 июн 2020, 10:42
Iq51
Синтаксис:
Используется 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;
        }
        ДЕЛАЕМ ЧТО-ТО ДАЛЕЕ
}