Інтеграція облачних сохранений та досягнень
Гравець пройшов 40 рівнів на iPhone, переставив гру на iPad — прогрес обнулився. Це не «дрібна недоробка». За даними кількох мобільних студій, втрата прогресу при переустановці входить у топ-3 причин негативних відзивів та відмови від гри. iCloud або Google Play Games Services вирішують проблему — але коректна інтеграція вимагає більше, ніж виклик одного методу.
Складності, які не видні до продакшену
Конфлікти при merge сохранень. Користувач грав офлайн на двох пристроях. Коли обидва підключилися — у вас два несумісних снапшоту прогресу. Apple Game Center та Google Play Games не вирішують за вас конфлікти: вони видають обидва снапшоту та чекають, поки клієнт виберет переможця. Без реалізованого conflict resolution з зрозумілим UI («Ваш прогрес на цьому пристрої: 43 рівня / У хмарі: 38 рівнів — що зберегти?») користувач отримає втрату даних.
Розмір та частота записів. Google Play Saved Games обмежує снапшот розміром 3 МБ, а загальний обсяг сохранень на аккаунт — 10 МБ (по замовчуванню). Якщо сохранення включає дані інвентарю з кількома тисячами записів — потрібно серіалізувати тільки дельту або оптимізувати формат. Часті автосохранення (після кожної дії) створюють чергу записів, яка при поганому з'єднанні накопичується та викликає GooglePlayGames.SavedGame.ISavedGameClient timeout.
Apple iCloud Keychain vs CloudKit. Для простих ігор достатньо NSUbiquitousKeyValueStore — синхронізує до 1 МБ пар ключ-значення. Для складного прогресу потрібен CloudKit з CKContainer та CKRecord. Unity не має нативного CloudKit binding — інтеграція вимагає написання Objective-C/Swift плагину або використання стороннього рішення типу CloudSave від Unity Gaming Services.
Unity Gaming Services Cloud Save
Для кроссплатформенних проектів (iOS + Android + PC) оптимальний шлях — Unity Cloud Save з пакету com.unity.services.cloudsave. Зберігає JSON-документи до 1 МБ, працює через Unity Authentication (анонімні аккаунти чи federated identity), підтримує server-side validation через Cloud Code.
Ключовой момент: CloudSaveService.Instance.Data.Player.SaveAsync() — асинхронний, кидає CloudSaveValidationException при перевищенні квот та CloudSaveException при мережевих помилках. Обробка цих виключень у продакшені обов'язкова — без неї втрата з'єднання в момент збереження ломає локальний кеш без діагностики.
Архітектура: локальне сохранення (PlayerPrefs чи кастомний JSON-файл у Application.persistentDataPath) + облачне як зеркало з version tag. При завантаженні — порівнюємо updatedAt із метаданних облачного снапшоту з локальним timestamp. Якщо розбіжність — інеціюємо conflict resolution flow.
Досягнення
Google Play Games Achievements та Apple Game Center Achievements — різні API, різні обмеження, різна логіка unlock. Правильна абстракція: IAchievementService з методами Unlock(achievementId), Increment(achievementId, steps), Report(achievementId, percent) — платформо-специфічна реалізація прихована за інтерфейсом.
Важлива деталь: incremental achievements у Google Play вимагають попередньої настройки totalSteps у Play Console. Якщо шаги змінилися (наприклад, досягнення «убий 100 ворогів» переробили на «убий 50») — не можна змінити total steps без скидання всього прогресу у існуючих користувачів. Це архітектурне рішення, яке потрібно приймати до релізу.
Для Game Center на iOS — обробка GKLocalPlayer.localPlayer.authenticateHandler з розгалуженням під випадки: аутентифікація успішна, користувач відмовився, Game Center недоступний. Останній сценарій часто ігнорують — а він трапляється у користувачів з обмеженими Family Sharing настройками.
Строки
| Платформа/сценарій | Строк |
|---|---|
| Google Play Games (досягнення + сохранення), одна платформа | 4–7 днів |
| Apple Game Center (досягнення + iCloud KVStore) | 4–7 днів |
| Unity Cloud Save (кроссплатформа) + conflict resolution UI | 1,5–2 тижні |
| Повна інтеграція iOS + Android + PC з кастомним бекендом | 3–5 тижнів |
Вартість розраховується індивідуально після аудиту ігрової архітектури та вимог до синхронізації прогресу.





