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

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

#0
21:38, 29 окт. 2017

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


#1
22:22, 29 окт. 2017

Пишите сохранения в файл(ы) по https://docs.unity3d.com/ScriptReference/Application-persistentDataPath.html

#2
22:25, 29 окт. 2017

KumoKairo
> Пишите сохранения в файл(ы)

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

#3
1:01, 30 окт. 2017

Фи, там делов то на 5 минут (с)

#4
7:50, 30 окт. 2017

Так вот кто системный реестр загаживает сохранениями игры...
PlayerPrefs — нужен для сохранения настроек между сессиями.
Если уж у тебя формат сохранений настолько примитивный создай аналогичный класс с тем же набором методов (но сохраняющий json/xml данные в Application.persistentDataPath) и автозаменой замени обращения к PlayerPrefs на свой класс.

#5
10:46, 30 окт. 2017

Вот метод, который сохраняет данные, как мне его переделать?

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();
    }
#6
12:10, 30 окт. 2017
Вот метод, который сохраняет данные, как мне его переделать?

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

Шаг 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);
}

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

#7
14:00, 30 окт. 2017

KumoKairo
Спасибо большое, сделал все как в ответе. А как мне теперь загружать данные, чтобы они загружались из определенного слота?
Если я раньше это делал так:

gameManagerScript.currentActNumber = PlayerPrefs.GetInt("act number" + currentActiveSlot);

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

gameManagerScript.currentActNumber = saves.actNumber + currentActiveSlot;
#8
14:28, 30 окт. 2017

Можете держать отдельный файл "save_stats" в котором хранится текущий активный слот и количество сейвов. Этот файл всегда будет один и его адрес всегда будет заранее известен.
Массивы если что тоже замечательно сериализуются

#9
15:53, 30 окт. 2017

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 соответственно, ошибка ушла

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

Тема в архиве.