Unity3d - C# - 如何备份数组的值?

时间:2017-07-18 07:06:09

标签: c# unity3d

我在脚本(C#)中定义了一个包含67个元素的数组。 每个元素都是我定义的类的对象,包括一些变量。 如下:

// the Definition of the array
public Pack[] packsInfo;

// the class 
[Serializable]
public class Pack
{
    public int number;
    public int angle;
    public float zPosition;
    public float beatCaseDistance;
    public float gunDistance;
}

然后,我在Inspector中分配所有值。如下:

enter image description here

所以...如果我突然改变任何值,或者更糟糕的是(价值因任何原因而消失。比如更改类参数或任何事物)那么我必须花费数小时来设置所有值。 所以我想打印文本或文件中的所有值并保存它们。以后再恢复它们。我想要一个备份解决方案。我想做这个编程。 (我不想手动写它们;)。浪费时间。 )

5 个答案:

答案 0 :(得分:1)

您可以通过创建一个编辑器脚本来实现此目的,该脚本获取阵列中的所有值并通过IO将它们保存到指定的文件中。从那里你可以轻松地创建一个带文件读取的加载功能。

以下是一些可以帮助您入门的链接:

Unity editor scripts

Unity read write file

答案 1 :(得分:1)

要保存yor数组,您可以使用例如JsonUtillity

很简单!祝你好运!

 void Start () {
    /////////////////////// save to json
    JSONObject jsonSave = new JSONObject();
    for(int i=0; i < packsInfo.Length; i++) {
        JSONObject packJson = new JSONObject();
        packJson.AddField("number", packsInfo[i].number);
        packJson.AddField("angle", packsInfo[i].angle);
        packJson.AddField("z_position", packsInfo[i].zPosition);
        packJson.AddField("beat_case_distance", packsInfo[i].beatCaseDistance);
        packJson.AddField("gun_distance", packsInfo[i].gunDistance);
        jsonSave.Add(packJson);
    }

    System.IO.StreamWriter streamWritter = new System.IO.StreamWriter(@"C:\MyGameFiles\packs.json");
    streamWritter.WriteLine(jsonSave.Print(true));
    streamWritter.Close();
    streamWritter = null;
    /////////////////////// read json
    System.IO.StreamReader reader = new System.IO.StreamReader(@"C:\MyGameFiles\packs.json");
    string jsonString = reader.ReadToEnd();
    reader.Close();
    reader = null;

    JSONObject jsonRead = new JSONObject(jsonString);
    packsInfo = new Pack[jsonRead.Count];
    for(int i =0; i < jsonRead.Count; i ++) {
        Pack pack = new Pack();
        pack.number = (int)jsonRead[i]["number"].i;
        pack.angle = (int)jsonRead[i]["angle"].i;
        pack.zPosition = jsonRead[i]["z_position"].f;
        pack.beatCaseDistance =jsonRead[i]["beat_case_distance"].f;
        pack.gunDistance = jsonRead[i]["gun_distance"].f;
        packsInfo[i] = pack;
    }
}

答案 2 :(得分:1)

我知道这已被多次回答,但我建议您使用Newtonsoft Json Library。它可以自动化对象的序列化和反序列化,因此当您更改json将适应的对象时,无需进行特定更改。

要序列化你只需这样做:

string json = JsonConvert.Serialise(packsInfo); //convert to text
File.WriteAllText(path, json); //Save to disk

要反序列化,只需执行以下操作:

string json = File.ReadAllLines(path); //load the file
packsInfo = JsonConvert.DeserializeObject<Pack[]>(json); //convert to an object

这就是保存和加载数据所需要做的一切。要获取库,您可以使用NuGet将库添加到项目中。在Visual Studio中转到工具 - &gt; NuGet包管理器 - &gt;管理解决方案的NuGet包,然后转到浏览选项卡并搜索它。

答案 3 :(得分:0)

如果您没有特别的理由在编辑器(公共)中序列化变量,我建议您将以下步骤公开删除:

  1. 使用JsonUtility并在设置所有值并打印时将类序列化为json。
  2. var json = JsonUtility.ToJson(packsInfo);
    Debug.Log(json);
    
    1. 现在,当您开始游戏时,该类将显示在您的控制台中,然后您可以复制该json并将其保存在文本文件中,例如“MyFile.txt”

    2. 将该文本文件添加到项目中,并使用以下任一方法将其加载到您的游戏中:

      • 为其创建公共字段并将文件拖到该字段:

          

        public TextAsset packInfoAsset;

      • 将其添加到名为Resources的文件夹中,然后使用以下代码获取该文件:

          

        var packInfoAsset = Resources.Load(“MyFile”); //请注意,没有文件结尾(.txt)

    3. 最后,将json反序列化为上一个对象,因此当您加载类时,在Start-method中,您可以执行以下操作:

      packsInfo = JsonUtility.FromJson<Pack>(packInfoAsset);

    4. 你去了,你已经从文件加载数据而不是在编辑器中加载。

答案 4 :(得分:0)

您可以将数据保存到ScriptableObject,然后将其存储为资产。

首先,使用ScriptableObject类包装数组:

using UnityEngine;
using System.Collections;

public class PacksInfo: ScriptableObject
{
    public Pack[] packs;
}

然后创建一个编辑器脚本以从Unity编辑器菜单生成ScriptableObject。

using UnityEngine;
using System.Collections;
using UnityEditor;

public class CreatePacksInfo
{
    [MenuItem("Assets/Create/Packs Info")]
    public static PacksInfo Create()
    {
        TextAsset json = (TextAsset) 
        AssetDatabase.LoadAssetAtPath("Assets/RawData/PacksInfo.json", 
        typeof(TextAsset));
        PacksInfo asset = ScriptableObject.CreateInstance<PacksInfo>();
        JsonUtility.FromJsonOverwrite(json.text, asset);

        AssetDatabase.CreateAsset(asset, "Assets/Data/PacksInfo.asset");
        AssetDatabase.SaveAssets();
        return asset;
    }
}

在这种情况下,我基于json文件创建资产。如果您想在Unity Editor中手动填充它们,还可以将数组分配给PackInfo对象。

当您想要使用数据时,您只需声明一个PackInfo变量:

public class something: MonoBehaviour
{
    public PacksInfo packsInfo;
}

然后将您直接从Unity编辑器生成的ScriptableObject资产拖到检查器中的变量。