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

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

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

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

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

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

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

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

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

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

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

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

Настройка Addressables Assets

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Теперь нам осталось реализовать загрузку сцен через 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 вынося контент за пределы билда.

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

5858
10 комментариев

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

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

9
Ответить

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

2
Ответить

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

Ответить

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

2
Ответить

Да, все верно

Ответить

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

1
Ответить

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

1
Ответить