Что нужно знать о сохранении данных в Unity3D


Привет! Очередные фичи были запилены, очередные баги были зафикшены. А возникли они почти на пустом месте.

И так, предисловие

Делаем мы значит проект. Для сохранения данных используем SQLite, стандатрный PlayerPrefs.

Покупки и баланс пользователя хранит Soomla.

И после очередного обновления вдруг выясняется, что игрок теряет весь прогресс прохождения, если обновиться до последней версии. Стали искать…

Internal vs External Storage

На андроиде есть понятие внешняя(External, карта памяти) и внутренняя(телефонная) память. Если у пользователя нет карты памяти, то можно использовать только внутреннюю. Если есть оба типа памяти, то можно выбрать, куда сохранять пользовательские данные.

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

Внешняя память имеет обычно больший объем и поэтому свободное место имеется, но минус в том, что карту могут извлечь или она придет в негодность.

Так что выбирайте сами, куда сохранять.

Настройка места сохранения

После того, как вы выбрали место под сохранение, нужно выполнить настройки.

Открыв Build Settings находим Install Location — эта настройка говорит о том, куда выполнится установка вашего приложения. Значения можно посмотреть в документации.

Более важная настройка — Write Access. Если стоит External, то приложение будет записывать данные во внешнюю память, т.е. Application.persistentDataPath будет указывать на папку на карте памяти.

Если поставить Internal Only, то данные запишутся во внутреннюю память.

AndroidManifest

Однако не все! Дело в том, что приложение может писать данные во внешнюю память, даже если у вас стоит Write Access -> Internal. Как?

Всему веной — WRITE_EXTERNAL_STORAGE. Если у вас в манифесте прописано это разрешение, то прилага будет писать данные во внешнюю память, игнорируя настройку Write Access.

Предположим, вам все же нужно разрешение для записи во внешнюю память(многие плагины требуют данное разрешение), но хранить данные вы намерены во внутренней памяти(а часть данных во внешней?). Что делать?

Явное указание пути

Вариант решения — явно указывать путь до файла во внутренней памяти, т.к. он статичен, в отличии от внешней(т к разные производители по-разному составляют путь до карты памяти)



public static string DbPath
{
   get{
#if UNITY_ANDROID && !UNITY_EDITOR
      return Path.Combine("data/data/com.MyCompany.MyApplication/files", "fileName.txt");//внутренняя память приложения
#else
      return Path.Combine(Application.persistentDataPath, "fileName.txt");//внешняя
#endif
   }
}



понятное дело, что com.MyCompany.MyApplication нужно заменить на ваш банд ид. Теперь смело ставим Write Access -> External и добавляем в манифест WRITE_EXTERNAL_STORAGE.

Не забывайте, что нужно проверять наличие свободного места на диске перед записью.

Удачной разработки!

ЗЫ На iOS таких проблем нет, т к там нет внешней памяти)

0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.