【问题标题】:Saving multiple slider values in playerprefs在 playerprefs 中保存多个滑块值
【发布时间】:2018-03-30 04:44:53
【问题描述】:

我遇到了一个问题,我只能将一个滑块值存储到 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;
        }

    }
}

【问题讨论】:

  • 不要在标题中加上“已解决”。

标签: c# unity3d


【解决方案1】:

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

使用FindObjectsOfType(typeof(Slider)) 获取滑块,然后序列化并保存。

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

例如,保存重要滑块值的对象:

[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 很好。

【讨论】:

  • 这可能有点超出我的理解范围 - 如果您有时间详细说明这些细节,我会很乐意尝试这种方法,因为我已经看到 10 个滑块值加载缓慢
  • 我的问题是我不知道如何将此代码合成到工作文件中。我不明白在哪里放 Slider[] slider = FindObjectsOfType(typeof(Slider)) as Slider[]; SliderInfo sliderInfo = new SliderInfo(slider);DataSaver.saveData(sliderInfo, "Sliders"); SliderInfo loadedSliders = DataSaver.loadData&lt;SliderInfo&gt;("Sliders");
  • 你把它放在你调用函数来保存文件的地方。在您的其他帖子中,您似乎想通过单击按钮进行保存,因此将其放入该按钮单击将调用的函数中。加载部分SliderInfo loadedSliders = DataSaver.loadData&lt;SliderInfo&gt;("Sliders"); 应该在Start 函数中,因为您想在游戏开始时加载它
  • 谢谢,用新代码编辑了我的帖子,但保存功能仍然存在一些问题。
  • 它正在保存和加载。您当前没有将加载的数据应用到滑块。我已经修改了您的 cod 并删除了无用的内容并添加了更多代码来解决问题。您仍然必须将加载的数据应用到滑块。查看我所做的编辑以及我所说的 "/*Loop overloadedSliders.sliders 然后将 objName 与slider.name 进行比较,如果它们匹配,则分配值*/".
【解决方案2】:

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

解决方法是给每个滑块一个唯一的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 都需要在场景中具有唯一名称。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多