Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / Сохранения в Steam

Сохранения в Steam

Поделиться
dmitrykozyrПостоялецwww29 окт. 201721:38#0
У меня игра на юнити и я для сохранения использую функцию PlayerPrefs.SetInt().
Загрузил игру в стим (она еще недоступна) и если потом загрузить в стим обновленную сборку, то все сохранения из старой сборки затираются новыми.
Как этого избежать? А то я когда после релиза буду баги править, я же не могу портить сохранения игроков

Правка: 29 окт. 2017 21:39

KumoKairoПостоялецwww29 окт. 201722:22#1
Пишите сохранения в файл(ы) по https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html
dmitrykozyrПостоялецwww29 окт. 201722:25#2
KumoKairo
> Пишите сохранения в файл(ы)

Мне бы желательно такое решение, чтобы не переделывать весь код, над которым я сидел два месяца

KumoKairoПостоялецwww30 окт. 20171:01#3
Фи, там делов то на 5 минут (с)
mahrizhПостоялецwww30 окт. 20177:50#4
Так вот кто системный реестр загаживает сохранениями игры...
PlayerPrefs — нужен для сохранения настроек между сессиями.
Если уж у тебя формат сохранений настолько примитивный создай аналогичный класс с тем же набором методов (но сохраняющий json/xml данные в Application.persistentDataPath) и автозаменой замени обращения к PlayerPrefs на свой класс.
dmitrykozyrПостоялецwww30 окт. 201710:46#5
Вот метод, который сохраняет данные, как мне его переделать?
public void ButtonSave()
    {
        PlayerPrefs.SetString("date time" + currentActiveSlot, System.DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss") + " ");
        PlayerPrefs.SetFloat("transform position x" + currentActiveSlot, playerTransform.position.x);
        PlayerPrefs.SetFloat("transform position y" + currentActiveSlot, playerTransform.position.y);
        PlayerPrefs.SetFloat("transform position z" + currentActiveSlot, playerTransform.position.z);
        PlayerPrefs.SetInt("latestSaveSlot", latestSaveSlot);
        PlayerPrefs.SetInt("act number" + currentActiveSlot, gameManagerScript.currentActNumber);
        PlayerPrefs.SetString("sceneName" + currentActiveSlot, SceneManager.GetActiveScene().name);
        PlayerPrefs.SetInt("slotImage" + currentActiveSlot, imageNumberForCurrentSlot);
        PlayerPrefs.Save();
    }

Правка: 30 окт. 2017 10:57

KumoKairoПостоялецwww30 окт. 201712:10#6
Вот метод, который сохраняет данные, как мне его переделать?

О, так это очень просто. У вас, во-первых, очень мало параметров для сохранений, а во вторых всё сохраняется целиком за один вызов. Поэтому можно при сохранении просто перезаписывать весь файл с настройками-сохранениями целиком.

Шаг 1:
Делаем Serializable POCO класс (https://en.wikipedia.org/wiki/Plain_old_CLR_object)

[Serializable]
public class Saves
{
    public string dateTime;
    public float transformPositionX;
    public float transformPositionY;
    public float transformPositionZ; // можно три координаты заменить на один Vector3, он сериализуем
    ....
    // и далее по вашему списку
}

Шаг 2:
В момент вашего ButtonSave заполняем этот объект данными:

public void ButtonSave()
{
  var myLittlePoco = new Saves();
  myLittlePoco.dateTime = System.DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss");
  myLittlePoco.transformPositionX = playerTransform.position.x;
  // Я всё же советую так 
  myLittlePoco.transformPosition = playerTransform.position;
  ...
}

Шаг 3:
Сериализуем в JSON с помощью JsonUtilty (https://docs.unity3d.com/ScriptReference/JsonUtility.html)

public void ButtonSave()
{
  ...
  var serializedSave = JsonUtility.ToJson(myLittlePoco);
}

Шаг 4:
Выбираем файл из сохранения по слотам (чтобы сохранить функционал слотов) и пишем

public void ButtonSave()
{
  ...
  var saveFileName = Application.persistentDataPath + "/Save_" + currentActiveSlot + ".save";
  File.WriteAllText(saveFileName, serializedSave);
}

Точный синтаксис и логику вызовов надо проверить, набирал в блокноте

dmitrykozyrПостоялецwww30 окт. 201714:00#7
KumoKairo
Спасибо большое, сделал все как в ответе. А как мне теперь загружать данные, чтобы они загружались из определенного слота?
Если я раньше это делал так:
gameManagerScript.currentActNumber = PlayerPrefs.GetInt("act number" + currentActiveSlot);

то теперь так не получится, т.к. уже значение переменной меняется:

gameManagerScript.currentActNumber = saves.actNumber + currentActiveSlot;
KumoKairoПостоялецwww30 окт. 201714:28#8
Можете держать отдельный файл "save_stats" в котором хранится текущий активный слот и количество сейвов. Этот файл всегда будет один и его адрес всегда будет заранее известен.
Массивы если что тоже замечательно сериализуются

Правка: 30 окт. 2017 14:29

dmitrykozyrПостоялецwww30 окт. 201715:53#9
KumoKairo
Сохранение работает, а вот с загрузкой застрял. Не совсем понял с отдельным файлом, сделал вот так:
    public void ButtonLoad()
    {      
        var saveFileName = Application.persistentDataPath + "/Save_" + currentActiveSlot + ".save";
        var saveFilecontent = File.ReadAllText(saveFileName);
        var deSerializedSave = JsonUtility.FromJson<Saves>(saveFilecontent);
        saves = deSerializedSave;
    }

По идее  после этого когда мне не нужно указывать номер слота и можно просто обращаться к сохраненным переменным из класса Saves. Но при попытке загрузить сохранение выдает ошибку "Cannot deserialize JSON to new instances of type 'Saves".

2 | Сохранения в Steam

Правка

Заменил var на string и Saves соответственно, ошибка ушла

Правка: 30 окт. 2017 16:18

/ Форум / Программирование игр / Игровая логика и ИИ

2001—2017 © GameDev.ru — Разработка игр