TGViewer
Unity Architect: архитектура unity проектов Unity Architect: архитектура unity проектов @uniarchitect · 5.23K subscribers
Post #140 8.76K
КАЧАЕМ ФАЙЛЫ БЫСТРЕЕ НА 30%

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

Контента в игре у вас много, а размер билда должен быть <150МБ.
Потому часть вы запаковали в 100 Asset Bundle'ов.
А на старте игры качаете их из CDN через Unity Web Request.

В коде это выглядит примерно так:
IEnumerator DownloadAssetBundle(string url, Action<byte[]> onSuccess)
{
using var request = UnityWebRequestAssetBundle.GetAssetBundle(url);
var op = request.SendWebRequest();

while (!op.isDone)
yield return null;
onSuccess?.Invoke(request.downloadHandler.data);
}

Уверен что у каждого в проекте есть похожий кусок.
Есть идеи как его ускорить? 😬

Ответ:
Application.targetFrameRate = 120


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

🔸Как так получается?
— Если вы знаете что такое Synchronization Context, то возможно, вы уже догадываетесь в чем дело.
Это специальный класс в dotnet, который представляет из себя очередь delegate'ов на MoveNext (машин состояний), которые будут вызваны в момент когда наше приложение готово продолжить выполнение асинхронного кода.

В unity синхронизация вызывается в UnityEngine.PlayerLoop.Update.ScriptRunDelayedTasks из нативной части, путем вызова статического метода UnitySynchronizationContext.ExecuteTasks.

🔸Или проще говоря:
— Все продолжения ваших асинхронных операций длиннее одного кадра будут вызваны на следующий кадр в Update.ScriptRunDelayedTasks фазе.

🔸Риторический вопрос:
Действительно ли время загрузки файлов по сети привязано к длине кадра?
— Вообще нет. Установление соединения и скачивание идет в другом потоке в нативной части.

Но вот результаты и обновление состояний синхронизированы с основным потоком и происходят в UnityEngine.PlayerLoop.EarlyUpdate.UnityWebRequestUpdate.

🔸Это значит:
Что если файл качается 45ms, а ваша игра работает при 30FPS, то ~15ms данные будут ждать синхронизации.
Того самого вызова MoveNext для вашего метода DownloadAssetBundle.

Т.е. данные в памяти в нативной части будут через 45ms, но у себя вы их получите только через 66ms.
И буст (местами до 30%) можно получить как раз за счет снижения времени "простоя" данных в ожидании вызова нужной фазы PlayerLoop'а.

Это тот забавный случай, когда магическая строчка в одном месте почему-то дает ощутимый результат 🤣
Так что, как идею, берите на вооружение увеличение FPS на время загрузки и возвращение его в нормальное значение после 😅

❗️Но блин, ребят, это не silver bullet. Проверяйте последствия на своих проектах.
На слабых девайсах это может только сделать хуже.

Если интересно копнуть больше в эту тему, рекомендую посмотреть видео с конференции CLRium.
CLRium #6: Контексты синхронизации (SynchronizationContext)

У меня огромная куча тем по архитектуре которым хочется с вами поделиться, но пока я сильно загружен ведением курса.
Статьи пока выходят редко, но блог не заброшен, вернусь совсем скоро как закончу курс 🫡

Ставь 👍 если тебе по кайфу такая движуха.

#будни@UniArchitect
  • 👍 109
  • 🔥 10
More from @uniarchitect
  1. Jul 24, 2026Post #199
  2. Jul 12, 2026AI НЕ ДЕЛАЕТ ВАС ПРОДУКТИВНЕЕ Незыблемый факт: AI уже очень хорош в маленьких задачах. Нап…
  3. Jul 9, 2026Post #196
  4. Jul 7, 2026UNITY BUILD PIPELINE ПО КИРПИЧИКАМ Полгода назад я решил попробовать активность в блоге, г…
  5. Jul 4, 2026ПРОКЛЯТИЕ ПЕРЕИСПОЛЬЗУЕМОСТИ Делюсь болью. Я последние 5 лет на разных уровнях у разработч…
  6. Jun 29, 2026AI КАК РЕДАКТОР, А НЕ АВТОР Это вторая статья из серии про AI. Первая тут. Когда я запуска…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →