繁体   English   中英

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

[英]Unity3d - C# - How can I back up of values of an array?

我在脚本(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中分配所有值。 如下所示:

在此处输入图片说明

所以...如果我突然更改了任何值甚至更糟((由于某种原因这些值消失了,例如更改类参数或任何东西),那么我必须花几个小时来设置所有值。 所以我想将所有值打印在文本或文件中并保存。 以便稍后恢复它们。 我想要一个备份解决方案。我想用编程来做。 (我不想手动编写它们;)。这是浪费时间。

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

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

Unity编辑器脚本

Unity读写文件

要保存数组,可以使用例如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;
    }
}

我知道已经回答了很多次,但是我建议您使用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中,转到工具-> NuGet程序包管理器->管理解决方案的NuGet程序包,然后转到浏览选项卡并进行搜索。

如果您没有特殊理由要在编辑器中对变量进行序列化(公共),建议您按照以下步骤将其作为公共变量删除:

  1. 设置所有值并打印后,使用JsonUtility并将您的类序列化为json。

var json = JsonUtility.ToJson(packsInfo);
Debug.Log(json);
  1. 现在,当您开始游戏时,该类将显示在控制台中,然后您可以复制该json并将其保存在文本文件中,例如“ MyFile.txt”

  2. 将该文本文件添加到项目中,然后使用以下任何一种方法将其加载到游戏中:

    • 为此设置一个公共字段并将文件拖到该字段:

      公共TextAsset packInfoAsset;

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

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

  3. 最后,将json反序列化为先前的对象,这样,当您在Start方法中加载类时,您可以执行以下操作:

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

然后,您就从文件中加载了数据,而不是将其保存在编辑器中。

您可以将数据保存到可以存储为资产的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编辑器中手动填充它们,则还可以将数组分配给PackInfo对象。

当您想使用数据时,可以声明一个PackInfo变量:

public class something: MonoBehaviour
{
    public PacksInfo packsInfo;
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM