PlayerPrefs на android не сохраняет.

Программирование для iPhone & Android

PlayerPrefs на android не сохраняет.

Сообщение milolga 30 июл 2018, 13:36

Всем доброго времени суток!!!
Помогите, пожалуйста! Уже неделю ищу ответ на свой вопрос на просторах интернета, ничего не помогает((( ~x(
Проблема такая:
Написала скрипт с сохранением в PlayerPrefs, на компе все работает на Ура!
При установке игры на телефон, не сохраняются данные вообще, при закрытии приложения и входе заново, все PlayerPrefs принимают начальные значения.
Пробовала сохранять после каждой строчки PlayerPrefs.SetInt(); писать PlayerPrefs.Save(); не помогает.
Пробовала :
Синтаксис:
Используется csharp
IEnumerator soxranenie()
    {

        yield return new WaitForSeconds(0.5f);
        PlayerPrefs.Save();

    }
    public void OnApplicationQuit()
    {
        PlayerPrefs.Save();

    }

    public void OnApplicationPause(bool pause)
    {
        if (pause)
        {
            PlayerPrefs.Save();
        }
    }
 


не помогает!(((
У меня много файлов с PlayerPrefs, везде прописала, а также сделала отдельный файл, тоже не помогает.
Примерный кусок:
Синтаксис:
Используется csharp
void sob_ymen_vodi()
    {
        if (PlayerPrefs.GetInt("k1_voda") > 0)
        {
            PlayerPrefs.SetInt("k1_voda", PlayerPrefs.GetInt("k1_voda") - 5);
            PlayerPrefs.Save();
        }
        else
        {
            PlayerPrefs.SetInt("k1_voda", 0);
            PlayerPrefs.Save();
        }

    }
 




Еще кусок:
Синтаксис:
Используется csharp
void Start () {
       
        StartCoroutine(soxranenie());

        if (!PlayerPrefs.HasKey("money_coins"))
        {
            PlayerPrefs.SetInt("money_coins", 101);
        }
        if (!PlayerPrefs.HasKey("money_dol"))
        {
            PlayerPrefs.SetInt("money_dol", 1);
        }
        if (!PlayerPrefs.HasKey("kol_korov"))
        {
            PlayerPrefs.SetInt("kol_korov", 0);
        }
        else
        {
            PlayerPrefs.SetInt("kol_korov", PlayerPrefs.GetInt("inv_korova") - PlayerPrefs.GetInt("kol_kor_napole"));
        }
       ...................................................................................................................

        PlayerPrefs.SetInt("kol_korov", PlayerPrefs.GetInt("inv_korova") - PlayerPrefs.GetInt("kol_kor_napole"));
        PlayerPrefs.SetInt("kolvo_telyat", PlayerPrefs.GetInt("inv_telyat") - PlayerPrefs.GetInt("tel_na_pole"));
        PlayerPrefs.SetInt("kol_bik", PlayerPrefs.GetInt("inv_bik") - PlayerPrefs.GetInt("kol_bik_napole"));

        .................................................................................................................

        k1_gizni = PlayerPrefs.GetFloat("k1_gizni");
        k2_gizni = PlayerPrefs.GetFloat("k2_gizni");
        k3_gizni = PlayerPrefs.GetFloat("k3_gizni");
        k4_gizni = PlayerPrefs.GetFloat("k4_gizni");
        k5_gizni = PlayerPrefs.GetFloat("k5_gizni");
        k6_gizni = PlayerPrefs.GetFloat("k6_gizni");
        k7_gizni = PlayerPrefs.GetFloat("k7_gizni");
        k8_gizni = PlayerPrefs.GetFloat("k8_gizni");
        k9_gizni = PlayerPrefs.GetFloat("k9_gizni");
        k10_gizni = PlayerPrefs.GetFloat("k10_gizni");

       ..........................................................

    }
   
    IEnumerator soxranenie()
    {

        yield return new WaitForSeconds(5f);
        PlayerPrefs.Save();

    }

    public void OnApplicationQuit()
    {
        PlayerPrefs.Save();
       
    }

    public void OnApplicationPause(bool pause)
    {
        if(pause)
        {
            PlayerPrefs.Save();
        }
    }
}
 




В чем может быть проблема?
Я читала, что PlayerPrefs сохраняет данные на андроиде в xml файле, но в этом у меня тоже проблема, до PlayerPrefs я пыталась сохранить все в xml файле, файлы xml на андроиде тоже не видит.
Может у меня что в коде не правильно? Или может надо где-то, что-то прописать в конфигурациях?
Помогите, пожалуйста!!! Моя фантазия уже заканчивается (не знаю где искать ошибку), и честно заново переписывать скрипты с сохранением другими вариантами уже не хочется)))
milolga
UNец
 
Сообщения: 3
Зарегистрирован: 30 июл 2018, 13:05

Re: PlayerPrefs на android не сохраняет.

Сообщение 1max1 30 июл 2018, 14:04

загляни в директорию /data/data/com.company.appname/shared_prefs/ там должны быть твои сохранения

com.company.appname это то что ты в player setting устанавливала other settings - packcage name
Аватара пользователя
1max1
Адепт
 
Сообщения: 5059
Зарегистрирован: 28 июн 2017, 10:51

Re: PlayerPrefs на android не сохраняет.

Сообщение milolga 30 июл 2018, 14:28

У меня даже папки такой нет(
по пути Android>data>com.F...> есть две папки : cache и files, обе пустые.
milolga
UNец
 
Сообщения: 3
Зарегистрирован: 30 июл 2018, 13:05

Re: PlayerPrefs на android не сохраняет.

Сообщение 1max1 30 июл 2018, 14:51

тебе нужен рут чтобы увидеть эту папку, она не Android она сразу в корне
Аватара пользователя
1max1
Адепт
 
Сообщения: 5059
Зарегистрирован: 28 июн 2017, 10:51

Re: PlayerPrefs на android не сохраняет.

Сообщение milolga 30 июл 2018, 18:47

Спасибо, ошибку нашла)
Все работает)))
milolga
UNец
 
Сообщения: 3
Зарегистрирован: 30 июл 2018, 13:05

Re: PlayerPrefs на android не сохраняет.

Сообщение at0mGaming 24 ноя 2021, 08:09

milolga писал(а):Спасибо, ошибку нашла)
Все работает)))

Столкнулся с такой же проблемой и не знаю, как решить. В Unity всё работает, создаю build для PC или android и PlayerPrefs не работают, а почему - не понимаю. Если кто-то будет готов помочь, с радостью выслушаю
at0mGaming
UNец
 
Сообщения: 16
Зарегистрирован: 23 ноя 2021, 22:18

Re: PlayerPrefs на android не сохраняет.

Сообщение DbIMok 24 ноя 2021, 16:10

скорее всего ошибка в логике
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > Telegram чат @unity3d_ru (9300+) > Telegram канал @unity_news (3600+) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6284
Зарегистрирован: 31 июл 2009, 14:05

Re: PlayerPrefs на android не сохраняет.

Сообщение at0mGaming 24 ноя 2021, 20:05

DbIMok писал(а):скорее всего ошибка в логике

Был бы очень признателен, если бы вы помогли мне найти ошибку.
Реализовал таблицу рекордов. Реализовал запись в неё. Всё классно работает, начинаю тестировать на android, запись в таблицу не происходит. Собираю билд для PC - то же самое. Нахожу где хранятся PlayerPrefs - там пусто. Как я понял, запись не происходит, потому что просто не понятно, куда записывать, какие-то проблемы с ключом hightScoreTable, возможно он инициализирован как-то не так. Был совет инициализировать PlayerPrefs пустой строкой, чтобы загруженный объект не был нулевым, но я не уверен что понимаю как это сделать, сделал через if в начале.
Синтаксис:
Используется csharp
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class highScoreTable : MonoBehaviour {
    private Transform entryContainer;
    private Transform entryTemplate;
    // private List<HightScoreEntry> hightScoreEntryList;
    private List<Transform> hightScoreEntryTransformList;

    public void Awake() {
        entryContainer = transform.Find("highScoreEntryContainer");
        entryTemplate = entryContainer.Find("highScoreEntryTemplate");

        entryTemplate.gameObject.SetActive(false);

        string jsonString = PlayerPrefs.GetString("hightScoreTable"); //инициализация
        HightScore hightscore =  JsonUtility.FromJson<HightScore>(jsonString);

        if(hightscore.hightScoreEntryList.Count == 0) {
             // если таблица пустая, записываем туда элемент
            // одним из таких способов пробовал решить проблему, в Unity создаётся, но когда собираем build - нет
            HightScoreEntry firstHightScore = new HightScoreEntry { score = 1, name = "test"};

            string jsonString1 = PlayerPrefs.GetString("hightScoreTable");
            HightScore hightscore1 =  JsonUtility.FromJson<HightScore>(jsonString1);
           
            hightscore1.hightScoreEntryList.Add(firstHightScore);
           
            string json = JsonUtility.ToJson(hightscore1);
            PlayerPrefs.SetString("hightScoreTable", json);
            PlayerPrefs.Save();
        }

        for(int i = 0; i < hightscore.hightScoreEntryList.Count; i++) { // сортируем массива и его пересохранение
            for(int j = i + 1; j < hightscore.hightScoreEntryList.Count; j++) {
                if(hightscore.hightScoreEntryList[j].score > hightscore.hightScoreEntryList[i].score) {
                    HightScoreEntry tmp = hightscore.hightScoreEntryList[i];
                    hightscore.hightScoreEntryList[i] = hightscore.hightScoreEntryList[j];
                    hightscore.hightScoreEntryList[j] = tmp;

                    string json = JsonUtility.ToJson(hightscore); // перезаписываем отсортированный массив
                    PlayerPrefs.SetString("hightScoreTable", json);
                    PlayerPrefs.Save();
                }
            }
        }
        int n=10; // цикл для удаления лишних элементов из List, а т.к он отсортирован в цикле выше, то удаляется просто наименьший 11ый результат
        int k = hightscore.hightScoreEntryList.Count; // цикл выполняется столько раз, сколько лишних элементов (>10) в List
        for (int i = 0; i < (hightscore.hightScoreEntryList.Count - n); i ++ ) {
            if(hightscore.hightScoreEntryList.Count > n) {
                hightscore.hightScoreEntryList.RemoveAt(k-1);
                string json = JsonUtility.ToJson(hightscore);
                PlayerPrefs.SetString("hightScoreTable", json);
                PlayerPrefs.Save();
                Debug.Log(hightscore.hightScoreEntryList.Count);
                Debug.Log(PlayerPrefs.GetString("hightScoreTable"));
            }
        }

        Debug.Log(PlayerPrefs.GetString("hightScoreTable"));
        hightScoreEntryTransformList = new List<Transform>();  
        foreach (HightScoreEntry hightScoreEntry in hightscore.hightScoreEntryList) { //отрисовка строк таблицы рекордов
            createHightScoreEntryTransform(hightScoreEntry, entryContainer, hightScoreEntryTransformList);
        }
    }

    public void createHightScoreEntryTransform(HightScoreEntry hightScoreEntry, Transform container, List<Transform> transformList) {
        float templateHight = 45f;
        Transform entryTransform = Instantiate(entryTemplate, container);
        RectTransform entryRectTransform = entryTransform.GetComponent<RectTransform>();
        entryRectTransform.anchoredPosition = new Vector2(0, -templateHight * transformList.Count);
        entryTransform.gameObject.SetActive(true);

        int rank = transformList.Count +1;
        string rankString;
        switch(rank) {
            default:
                rankString = rank + ""; break;
            case 1:
                rankString = rank + "ый"; break;
            case 2:
                rankString = rank + "ой"; break;
            case 3:
                rankString = rank + "ий"; break;
        }
        entryTransform.Find("position (1)").GetComponent<Text>().text = rankString;

        int score = hightScoreEntry.score;
        entryTransform.Find("score (1)").GetComponent<Text>().text = score.ToString();
       
        string name = hightScoreEntry.name;
        entryTransform.Find("name (1)").GetComponent<Text>().text = name;

        transformList.Add(entryTransform);
    }

    public static void AddHightScoreEntry(int score, string name) { //метод для добавления новых данных
        HightScoreEntry hightScoreEntry = new HightScoreEntry { score = score, name = name};

        string jsonString = PlayerPrefs.GetString("hightScoreTable");
        HightScore hightscore =  JsonUtility.FromJson<HightScore>(jsonString);
       
        hightscore.hightScoreEntryList.Add(hightScoreEntry);
       
        string json = JsonUtility.ToJson(hightscore);
        PlayerPrefs.SetString("hightScoreTable", json);
        PlayerPrefs.Save();
    }

    public class HightScore {
        public List<HightScoreEntry> hightScoreEntryList;
    }

    [System.Serializable]
    public class HightScoreEntry {
        public int score;
        public string name;
    }
}
 
at0mGaming
UNец
 
Сообщения: 16
Зарегистрирован: 23 ноя 2021, 22:18

Re: PlayerPrefs на android не сохраняет.

Сообщение DbIMok 24 ноя 2021, 21:49

сделайте тест с двумя кнопками: Записать, Прочитать и тестируйте на нем
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > Telegram чат @unity3d_ru (9300+) > Telegram канал @unity_news (3600+) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6284
Зарегистрирован: 31 июл 2009, 14:05

Re: PlayerPrefs на android не сохраняет.

Сообщение at0mGaming 24 ноя 2021, 22:13

DbIMok писал(а):сделайте тест с двумя кнопками: Записать, Прочитать и тестируйте на нем

Это совет чисто для удобства тестирования? Просто я не понимаю как мне это поможет, ибо мне ничего не стоит пересобрать приложение и проверить в нём. Могу лог файл прикрепить, если это поможет
Ошибки выдаются при отображении таблицы:
Синтаксис:
Используется csharp
NullReferenceException: Object reference not set to an instance of an object
  at highScoreTable.Awake () [0x0004d] in <0f6f929ed0894b52ab258274d66c98b8>:0

И при нажатии на кнопку:
Синтаксис:
Используется csharp
NullReferenceException: Object reference not set to an instance of an object
  at highScoreTable.AddHightScoreEntry (System.Int32 score, System.String name) [0x00023] in <0f6f929ed0894b52ab258274d66c98b8>:0
at0mGaming
UNец
 
Сообщения: 16
Зарегистрирован: 23 ноя 2021, 22:18

Re: PlayerPrefs на android не сохраняет.

Сообщение 1max1 24 ноя 2021, 22:42

Тебе правда стоит говорить что одна из переменных null, и когда ты пытаешься к ней обратиться, то выбрасывается исключение и не дает коду пройти дальше? Тебе даже в логе сказали в каких методах это происходит. Не факт что это решит твою проблему, но как минимум такого нужно избегать.
Аватара пользователя
1max1
Адепт
 
Сообщения: 5059
Зарегистрирован: 28 июн 2017, 10:51

Re: PlayerPrefs на android не сохраняет.

Сообщение at0mGaming 24 ноя 2021, 23:08

1max1 писал(а):Тебе правда стоит говорить что одна из переменных null, и когда ты пытаешься к ней обратиться, то выбрасывается исключение и не дает коду пройти дальше? Тебе даже в логе сказали в каких методах это происходит. Не факт что это решит твою проблему, но как минимум такого нужно избегать.

Иногда, чтобы осознать какую-то очевидную вещь, стоит услышать её из других уст) Да и на форумах всегда стоит быть готовым к не самой приятной критике)
Что касается проблемы, я какие только способы не пробовал, но так и не пришёл к решению. Очевидно, что я чего-то не понимаю, уже всё что можно перечитал про PlayerPrefs, и не чувствую что это как-то помогло :(
at0mGaming
UNец
 
Сообщения: 16
Зарегистрирован: 23 ноя 2021, 22:18

Re: PlayerPrefs на android не сохраняет.

Сообщение samana 24 ноя 2021, 23:14

Попробовал как-то привести ваш код в более приемлемый вид (для моего восприятия).
Написал комментарии ( //-> ) там где поменял логику и прочее.
Ваш метод отрисовки createHightScoreEntryTransform не трогал (вроде), так как я не знаю что там происходит.

Попробуйте понять следующий код и как-то внедрить его в свой проект, либо оставить таким, если он подойдёт.
Любой дополнительный рефакторинг в ваших руках.

Синтаксис:
Используется csharp
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class highScoreTable : MonoBehaviour
{
    private Transform entryContainer;
    private Transform entryTemplate;
    private List<Transform> hightScoreEntryTransformList;

    //---------------------
    private const int MaxScoresInTable = 10; //-> максимальное кол-во рекордов в таблице
    private const string ScoreTableSaveKey = "ScoreTable.saveData"; //-> имя для сохранения в PlayerPrefs

    [Space]
    [Header("DebugSaveData")]
    [SerializeField]
    private ScoreTable _scoreTable; //-> отображение таблицы в инспектрое для дебага

    public void Awake()
    {
        entryContainer = transform.Find("highScoreEntryContainer");

        entryTemplate = entryContainer.Find("highScoreEntryTemplate");
        entryTemplate.gameObject.SetActive(false);

        hightScoreEntryTransformList = new List<Transform>();


        LoadTableOrDefault(); //-> загрузили таблицу, либо создали пустую, если сохранений не было

        //-> если таблица пустая, то добавляем тестовый сейв
        if (_scoreTable.IsEmpty)
            AddHightScoreAndSave(score: 1, name: "test");

        //-> обновляем UI таблицы
        RedrawTableUI();
    }
   
    public void AddHightScoreAndSave(int score, string name) //-> Добавление рекорда в таблицу и пересохранение
    {
        _scoreTable.AddScore(score, name);
        SaveTable();
    }

    public void SaveTable() //-> сохранение таблицы в PlayerPrefs
    {
        SortAndCutTable();
        PlayerPrefs.SetString(ScoreTableSaveKey, JsonUtility.ToJson(_scoreTable));
    }

    public void LoadTableOrDefault() //-> загружка таблицы из PlayerPrefs
    {
        _scoreTable = JsonUtility.FromJson<ScoreTable>(PlayerPrefs.GetString(ScoreTableSaveKey));
        _scoreTable = _scoreTable ?? new ScoreTable(); //-> если сохранения не было и вернуло NULL, то создаём новую таблицу
    }

    private void SortAndCutTable() //-> корректировка таблицы
    {
        _scoreTable.ScoresList = _scoreTable.ScoresList
                                                        .OrderByDescending(i => i.Score) //-> сортировка от большего к меньшему
                                                        .Take(MaxScoresInTable) //-> оставляем только нужное кол-во рекордов
                                                        .ToList();
    }

    private void RedrawTableUI()
    {
        foreach (ScoreData scoreData in _scoreTable.ScoresList)
        { //отрисовка строк таблицы рекордов
            createHightScoreEntryTransform(scoreData.Score, scoreData.Name, entryContainer, hightScoreEntryTransformList);
        }
    }
    private void createHightScoreEntryTransform(int score, string name, Transform container, List<Transform> transformList)
    {
        float templateHight = 45f;
        Transform entryTransform = Instantiate(entryTemplate, container);
        RectTransform entryRectTransform = entryTransform.GetComponent<RectTransform>();
        entryRectTransform.anchoredPosition = new Vector2(0, -templateHight * transformList.Count);
        entryTransform.gameObject.SetActive(true);

        int rank = transformList.Count + 1;
        string rankString;
        switch (rank)
        {
            default:
                rankString = rank + ""; break;
            case 1:
                rankString = rank + "ый"; break;
            case 2:
                rankString = rank + "ой"; break;
            case 3:
                rankString = rank + "ий"; break;
        }
        entryTransform.Find("position (1)").GetComponent<Text>().text = rankString;
        entryTransform.Find("score (1)").GetComponent<Text>().text = score.ToString();
        entryTransform.Find("name (1)").GetComponent<Text>().text = name;

        transformList.Add(entryTransform);
    }


    [System.Serializable]
    public class ScoreTable
    {
        public List<ScoreData> ScoresList = new List<ScoreData>();

        public bool IsEmpty => ScoresList.Count == 0;
        public void AddScore(int score, string name)
        {
            ScoresList.Add(new ScoreData(score, name));
        }
    }

    [System.Serializable]
    public class ScoreData
    {
        public int Score;
        public string Name;

        public ScoreData(int score, string name)
        {
            Score = score;
            Name = name;
        }
    }
}
 
Аватара пользователя
samana
Адепт
 
Сообщения: 4705
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: PlayerPrefs на android не сохраняет.

Сообщение DbIMok 24 ноя 2021, 23:41

Это совет чисто для удобства тестирования? Просто я не понимаю как мне это поможет

поможет понять, что дело не в PlayerPrefs, а в неправильной логике вокруг него
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > Telegram чат @unity3d_ru (9300+) > Telegram канал @unity_news (3600+) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6284
Зарегистрирован: 31 июл 2009, 14:05

Re: PlayerPrefs на android не сохраняет.

Сообщение at0mGaming 25 ноя 2021, 08:16

samana писал(а):Попробовал как-то привести ваш код в более приемлемый вид (для моего восприятия).
Написал комментарии ( //-> ) там где поменял логику и прочее.
Ваш метод отрисовки createHightScoreEntryTransform не трогал (вроде), так как я не знаю что там происходит.

Попробуйте понять следующий код и как-то внедрить его в свой проект, либо оставить таким, если он подойдёт.
Любой дополнительный рефакторинг в ваших руках.

Большое спасибо за такую понятную и полезную модификацию)! Я поработаю с предложенным вами вариантом и отпишусь при достижении каких-либо результатов
at0mGaming
UNец
 
Сообщения: 16
Зарегистрирован: 23 ноя 2021, 22:18

След.

Вернуться в iPhone & Android

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5