{"id":3974,"url":"\/distributions\/3974\/click?bit=1&hash=89c074744adc3963d1ee90e1903467ac5be17774d44e7968801238b3c2d5ae12","title":"\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 \u043d\u0430 \u0437\u0430\u0432\u043e\u0434\u0435? ","buttonText":"\u0423\u0437\u043d\u0430\u0442\u044c","imageUuid":"6ac5a19e-df76-5b67-a8ea-a69df4167a4d","isPaidAndBannersEnabled":false}

Организуем доставку контента в игре. Уменьшаем размер APK файла и включаем загрузку обновлений с сервера без вложений

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

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

И конечно же, перед началом работы определимся, что нам понадобиться:

  • Аккаунт на GitHub (или любом другом гите);
  • Проект на Unity;
  • Addressables для упаковки контента и обновлений;

Настройка GIT, как хранилище обновлений

На самом деле вы можете использовать хоть Google Drive или Google Cloud Platform, но предположим, что у нас небольшая игра, для которой хватит функционала GitHub.

Чтобы нам было проще доставлять обновления - подключите GitHub Pages для своего репозитория:

В нашем случае мы подключили даже домен ко всему этому делу, но не для красоты, а потому что у нас там еще статический сайт лежит :D

Теперь, по сути вы будете использовать URL с вашего сайта на GitHub для получения обновлений. Перейдем к настройке Addressables.

Настройка Addressables Assets

Теперь нам нужно настроить наш пакет для работы с обновлениями. Прежде всего нам нужно установить пакет Addressables при помощи Package Manager в Unity:

После чего нам нужно настроить профили Addressables. И указать в них URL для загрузки нашего контента:

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

Для каждой загружаемой группы также необходимо указать, что мы берем её с сервера:

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

Последний шаг - настроить основные параметры Addressables:

Нас интересует настройка "Build Remote Catalog":

В принципе все. Теперь мы можем собирать наш контент. А для сборки обновления мы должны использовать "Update Previous Build". Прикладываю скрин, чтобы не потерялись:

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

Теперь нам осталось реализовать загрузку сцен через Addressables.

Скрипт загрузки сцен

По своей сути данный скрипт не будет сильно отличаться от обычной загрузки сцены. Просто мы будем использовать Addressables вместо SceneManagement.

Так будет выглядеть функция загрузки контента:

private IEnumerator LoadSceneAsync(string sceneName, Action<float> onProgress = null, Action<AsyncOperation> onComplete = null, Action<string> onError = null) { var downloadScene = Addressables.LoadSceneAsync(sceneName, LoadSceneMode.Single, false); downloadScene.Completed += handle => { if (handle.Status == AsyncOperationStatus.Succeeded) { if (onComplete != null) { onComplete(handle.Result.ActivateAsync()); } else { handle.Result.ActivateAsync().allowSceneActivation = true; } } else if(handle.Status == AsyncOperationStatus.Failed) { onError?.Invoke(handle.OperationException.Message); } }; while (!downloadScene.IsDone) { var status = downloadScene.GetDownloadStatus(); float progress = status.Percent; if (onProgress != null) onProgress(progress); yield return null; } if (onProgress != null) onProgress(1f); /* yield return null; AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName); asyncOperation.allowSceneActivation = false; while (!asyncOperation.isDone) { //Output the current progress if (onProgress != null) onProgress(asyncOperation.progress); // Check if the load has finished if (asyncOperation.progress >= 0.9f) { if (onComplete != null) { onComplete(asyncOperation); } else { asyncOperation.allowSceneActivation = true; } } yield return null; }*/ }

В комментах в данной функции я указал обычную загрузку не через Addressables.

Готово. Теперь вы можете использовать загрузку сцен с сервера в ваших проектах.

Итого

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

Если у вас возникнут какие-то вопросы или предложения - всегда рад обсудить с вами!

0
10 комментариев
Написать комментарий...
Гриша Бржезинский

Но правилами гитхаба не разрешается такое использование pages, как я понимаю. И лимит на трафик 100gb в месяц тоже делает такое использование сомнительным.

Если кэш весит хотя бы 500mb, то это 200 человек аудитория получается?

Ответить
Развернуть ветку
Mikhail Gudkov

Там написано что это для примера. Так то в любом случае лучше иметь прокси CDN прослойку, что бы можно было быстро перебросить на другой сервис. Например на второй github pages =)

Ответить
Развернуть ветку
Artem Mordanov

На гихабе дают бесплатно место в облаке для хранения репозиториев?

Ответить
Развернуть ветку
Mikhail Gudkov

Это реальный вопрос или я чего-то не понял? Просто вы уже в интернете и могли зайти на гихаб и посмотреть что входит в бесплатный план https://github.com/pricing

Ответить
Развернуть ветку
Artem Mordanov

Там указано "500MB of Packages storage". Просто я не очень умный( Это 500 мб на пользователя? Или 500 мб на репозиторий? Если на репозиторий, то количество репозиториев ограничено?

Ответить
Развернуть ветку
Илья Сергеич
Автор

Packages это Packages (https://github.com/features/packages) - на них дается 500 мб. А вообще расклад такой - любой файл в репозитории не более 100 МБ, примерно размер репозитория максимальный - 100 гигов на любом тарифе насколько я знаю. Лимит пуша вроде как 2 гб. Вообще это все гуглиться.

Ответить
Развернуть ветку
Dizer

Для билдов под ПК, я так понимаю, суть та же?

Ответить
Развернуть ветку
Илья Сергеич
Автор

Да, все верно

Ответить
Развернуть ветку
Tory Svetlova

Идеально, минимум воды, максимум полезного содержания, большое спасибо за информацию 👍

Ответить
Развернуть ветку
Arabiy Ismailov

Вот еще по теме

Ответить
Развернуть ветку
Читать все 10 комментариев
null