在playerprefs中保存多个滑块值

时间:2018-03-26 20:22:14

标签: c# unity3d

我遇到的问题是我只能将一个滑块值存储到playerprefs。我有10个滑块,如果我附加这个脚本,它们都会继承层次结构中第一个滑块的保存值。

public Slider Slider;
public float valueofslider ;


void Start()
{
valueofslider = PlayerPrefs.GetFloat("valueofslider");
Slider.value = valueofslider;
}

void Update()
{

  valueofslider = Slider.value;

if (Input.GetKeyDown(KeyCode.S))
{
    PlayerPrefs.SetFloat("valueofslider", valueofslider);
    Debug.Log("save");
    }
 }

}

使用建议编辑代码以保存到Json,但当前不保存。不确定操作顺序是否正确。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using LitJson;
using System.Text;
using System.Web;
using System;

public class jsonbuttonserialize : MonoBehaviour
{
    [SerializeField]
    public class Sliders
    {
        public float value;
        public float minValue;
        public float maxValue;
        public bool wholeNumbers;

        public string objName;
    }

    [SerializeField]
    public class SliderInfo
    {
        public List<Sliders> sliders;

        public SliderInfo()
        {
            sliders = new List<Sliders>();
        }

        public SliderInfo(Slider[] slider)
        {
            sliders = new List<Sliders>();
            for (int i = 0; i < slider.Length; i++)
                AddSlider(slider[i]);
        }

        public void AddSlider(Slider slider)
        {
            Sliders tempSlider = new Sliders();

            tempSlider.value = slider.value;
            tempSlider.minValue = slider.minValue;
            tempSlider.maxValue = slider.maxValue;
            tempSlider.wholeNumbers = slider.wholeNumbers;

            tempSlider.objName = slider.name;
            sliders.Add(tempSlider);
        }
    }

    public class DataSaver
    {
        //Save Data
        public static void saveData<T>(T dataToSave, string dataFileName)
        {
            string tempPath = Path.Combine(Application.persistentDataPath, "data");
            tempPath = Path.Combine(tempPath, dataFileName + ".txt");

            //Convert To Json then to bytes
            string jsonData = JsonUtility.ToJson(dataToSave, true);
            byte[] jsonByte = Encoding.ASCII.GetBytes(jsonData);

            //Create Directory if it does not exist
            if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
            }
            //Debug.Log(path);

            try
            {
                File.WriteAllBytes(tempPath, jsonByte);
                Debug.Log("Saved Data to: " + tempPath.Replace("/", "\\"));
            }
            catch (Exception e)
            {
                Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/", "\\"));
                Debug.LogWarning("Error: " + e.Message);
            }
        }

        //Load Data
        public static T loadData<T>(string dataFileName)
        {
            string tempPath = Path.Combine(Application.persistentDataPath, "data");
            tempPath = Path.Combine(tempPath, dataFileName + ".txt");

            //Exit if Directory or File does not exist
            if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
            {
                Debug.LogWarning("Directory does not exist");
                return default(T);
            }

            if (!File.Exists(tempPath))
            {
                Debug.Log("File does not exist");
                return default(T);
            }

            //Load saved Json
            byte[] jsonByte = null;
            try
            {
                jsonByte = File.ReadAllBytes(tempPath);
                Debug.Log("Loaded Data from: " + tempPath.Replace("/", "\\"));
            }
            catch (Exception e)
            {
                Debug.LogWarning("Failed To Load Data from: " + tempPath.Replace("/", "\\"));
                Debug.LogWarning("Error: " + e.Message);
            }

            //Convert to json string
            string jsonData = Encoding.ASCII.GetString(jsonByte);

            //Convert to Object
            object resultValue = JsonUtility.FromJson<T>(jsonData);
            return (T)Convert.ChangeType(resultValue, typeof(T));
        }

        public static bool deleteData(string dataFileName)
        {
            bool success = false;

            //Load Data
            string tempPath = Path.Combine(Application.persistentDataPath, "data");
            tempPath = Path.Combine(tempPath, dataFileName + ".txt");

            //Exit if Directory or File does not exist
            if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
            {
                Debug.LogWarning("Directory does not exist");
                return false;
            }

            if (!File.Exists(tempPath))
            {
                Debug.Log("File does not exist");
                return false;
            }

            try
            {
                File.Delete(tempPath);
                Debug.Log("Data deleted from: " + tempPath.Replace("/", "\\"));
                success = true;
            }
            catch (Exception e)
            {
                Debug.LogWarning("Failed To Delete Data: " + e.Message);
            }

            return success;
        }
    }

    public class buttonsave : MonoBehaviour
    {
        SliderInfo loadedSliders;
        Slider[] slider;

        void Start()
        {   
            //Load Slider Settings
            loadedSliders = DataSaver.loadData<SliderInfo>("Sliders");

            //Get current sliders in the Scene
            slider = FindObjectsOfType(typeof(Slider)) as Slider[];

            /*Loop over loadedSliders.sliders then compare the objName with
              slider.name, if they match, assign the value*/
        }

        void Update()
        {
            if (Input.GetKeyDown(KeyCode.S))
            {
                Slider[] slider = FindObjectsOfType(typeof(Slider)) as Slider[];
                SliderInfo sliderInfo = new SliderInfo(slider);
                //Save Sliders
                DataSaver.saveData(sliderInfo, "Sliders");
            }
        }
    }
}

使用更新的代码编辑,保存名为Sliders.txt的文件,但文件中没有记录数据...

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.IO;
using System.Text;
using System;

public class JSONSerialize:MonoBehaviour {
    [SerializeField]
    public class Sliders {
        public float value;
        public float minValue;
        public float maxValue;
        public bool wholeNumbers;
        public string objName;
    }


    SliderInfo loadedSliders;
    Slider[] slider;

    void Start() {
        //Load Slider Settings
        loadedSliders = DataSaver.loadData<SliderInfo>("Sliders");

        //Get current sliders in the Scene
        slider = FindObjectsOfType(typeof(Slider)) as Slider[];


    }

    void Update() {
        if (Input.GetKeyDown(KeyCode.S)) {
            Slider[] slider = FindObjectsOfType(typeof(Slider)) as Slider[];
            SliderInfo sliderInfo = new SliderInfo(slider);
            //Save Sliders
            DataSaver.saveData(sliderInfo,"Sliders");
            Debug.Log("hello");
        }
    }

    [SerializeField]
    public class SliderInfo {
        public List<Sliders> sliders;

        public SliderInfo() {
            sliders = new List<Sliders>();
        }

        public SliderInfo(Slider[] slider) {
            sliders = new List<Sliders>();
            for (int i = 0; i < slider.Length; i++)
                AddSlider(slider[i]);
        }

        public void AddSlider(Slider slider) {
            Sliders tempSlider = new Sliders();

            tempSlider.value = slider.value;
            tempSlider.minValue = slider.minValue;
            tempSlider.maxValue = slider.maxValue;
            tempSlider.wholeNumbers = slider.wholeNumbers;

            tempSlider.objName = slider.name;
            sliders.Add(tempSlider);
        }
    }

    public class DataSaver {
        //Save Data
        public static void saveData<T>(T dataToSave,string dataFileName) {
            string tempPath = Path.Combine(Application.persistentDataPath,"data");
            tempPath = Path.Combine(tempPath,dataFileName + ".txt");

            //Convert To Json then to bytes
            string jsonData = JsonUtility.ToJson(dataToSave,true);
            byte[] jsonByte = Encoding.ASCII.GetBytes(jsonData);

            //Create Directory if it does not exist
            if (!Directory.Exists(Path.GetDirectoryName(tempPath))) {
                Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
            }
            //Debug.Log(path);

            try {
                File.WriteAllBytes(tempPath,jsonByte);
                Debug.Log("Saved Data to: " + tempPath.Replace("/","\\"));
            } catch (Exception e) {
                Debug.LogWarning("Failed To PlayerInfo Data to: " + tempPath.Replace("/","\\"));
                Debug.LogWarning("Error: " + e.Message);
            }
        }

        //Load Data
        public static T loadData<T>(string dataFileName) {
            string tempPath = Path.Combine(Application.persistentDataPath,"data");
            tempPath = Path.Combine(tempPath,dataFileName + ".txt");

            //Exit if Directory or File does not exist
            if (!Directory.Exists(Path.GetDirectoryName(tempPath))) {
                Debug.LogWarning("Directory does not exist");
                return default(T);
            }

            if (!File.Exists(tempPath)) {
                Debug.Log("File does not exist");
                return default(T);
            }

            //Load saved Json
            byte[] jsonByte = null;
            try {
                jsonByte = File.ReadAllBytes(tempPath);
                Debug.Log("Loaded Data from: " + tempPath.Replace("/","\\"));
            } catch (Exception e) {
                Debug.LogWarning("Failed To Load Data from: " + tempPath.Replace("/","\\"));
                Debug.LogWarning("Error: " + e.Message);
            }

            //Convert to json string
            string jsonData = Encoding.ASCII.GetString(jsonByte);

            //Convert to Object
            object resultValue = JsonUtility.FromJson<T>(jsonData);
            return (T)Convert.ChangeType(resultValue,typeof(T));
        }

        public static bool deleteData(string dataFileName) {
            bool success = false;

            //Load Data
            string tempPath = Path.Combine(Application.persistentDataPath,"data");
            tempPath = Path.Combine(tempPath,dataFileName + ".txt");

            //Exit if Directory or File does not exist
            if (!Directory.Exists(Path.GetDirectoryName(tempPath))) {
                Debug.LogWarning("Directory does not exist");
                return false;
            }

            if (!File.Exists(tempPath)) {
                Debug.Log("File does not exist");
                return false;
            }

            try {
                File.Delete(tempPath);
                Debug.Log("Data deleted from: " + tempPath.Replace("/","\\"));
                success = true;
            } catch (Exception e) {
                Debug.LogWarning("Failed To Delete Data: " + e.Message);
            }

            return success;
        }

    }
}

2 个答案:

答案 0 :(得分:1)

脚本的所有实例都在更改一个键。最好在脚本的一个实例中执行此操作。这消除了覆盖现有密钥的机会。此外,由于您要保存许多滑块,因此您应该放弃使用PlayerPrefs并使用json和xml,然后手动将其另存为文件。

获取带有FindObjectsOfType(typeof(Slider))的滑块,然后序列化并保存。

保存滑块的最小值,最大值,整数和名称也很重要,这样您就可以使用这些信息重新创建滑块。

例如,包含重要滑块值的Object:

[SerializeField]
public class Sliders
{
    public float value;
    public float minValue;
    public float maxValue;
    public bool wholeNumbers;

    public string objName;
}

一个包装器,可以更容易地序列化滑块列表:

[SerializeField]
public class SliderInfo
{
    public List<Sliders> sliders;

    public SliderInfo()
    {
        sliders = new List<Sliders>();
    }

    public SliderInfo(Slider[] slider)
    {
        sliders = new List<Sliders>();
        for (int i = 0; i < slider.Length; i++)
            AddSlider(slider[i]);
    }

    public void AddSlider(Slider slider)
    {
        Sliders tempSlider = new Sliders();

        tempSlider.value = slider.value;
        tempSlider.minValue = slider.minValue;
        tempSlider.maxValue = slider.maxValue;
        tempSlider.wholeNumbers = slider.wholeNumbers;

        tempSlider.objName = slider.name;
        sliders.Add(tempSlider);
    }
}

如何使用

this帖子中抓取DataSaver课程。

获取所有幻灯片:

Slider[] slider = FindObjectsOfType(typeof(Slider)) as Slider[];

转换为准备保存的对象列表:

SliderInfo sliderInfo = new SliderInfo(slider);

保存:

DataSaver.saveData(sliderInfo, "Sliders");

负载:

SliderInfo loadedSliders = DataSaver.loadData<SliderInfo>("Sliders");

您可以在运行时使用loadedSliders变量recreate滑块。

注意:

这应该只附加到一个GameObject而不是场景中的每个Slider。空GameObject很好。

答案 1 :(得分:0)

您正在将滑块值保存到同一个键,导致每次都覆盖该键,在您的情况下是层次结构中第一个滑块的值。

解决问题的方法是为每个滑块指定一个唯一的PlayerPrefs键。

解决问题的一种快捷方法是更改​​

valueofslider = PlayerPrefs.GetFloat("valueofslider");
PlayerPrefs.SetFloat("valueofslider", valueofslider);

valueofslider = PlayerPrefs.GetFloat(gameObject.name + "valueofslider");
PlayerPrefs.SetFloat(gameObject.name + "valueofslider", valueofslider);

使用gameObject.name + "valueofslider"获取唯一键。为此,脚本附加到的每个Game Object都需要在场景中使用唯一的名称。

这只是解决问题的一种方法,还有很多其他更好的解决方法。