简体   繁体   中英

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

I Defined an array of 67 elements in a script (C#). Each element is an object of a class that I defined that includes some variables. Like Below:

// 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;
}

Then, I Assign all the values in Inspector. like Below:

在此处输入图片说明

So ... if i suddenly change any of the values or even worse, ( the values gone for a any reason. like changing the class parameters or any thing ) then I must spend hours on setting up all the values. So i want to print all the values in a text, or a file and save them. for recovering them later. i want a backup solution.I want to do it whit Programming. ( I don't want to write them manually ;) .It is waste of time. )

You can achieve this by creating an editor script that gets all the values in your array and saves them to specified file via IO. From there you can easily make a load function with file reading.

Here's some links to get you started:

Unity editor scripts

Unity read write file

To save yor array you can use for example JsonUtillity .

It is simple! Good Luck!

 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;
    }
}

I know that this has been answered many times but I would recommend you use the Newtonsoft Json Library . It automates the serialisation and deserialisation of objects for you so as you change the object the json will adapt without having to make specific changes.

To Serialise you simply do this:

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

To deserialise you simply do this:

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

That's all you have to do to save and load your data. To get the Library you can use NuGet to add the library to the project. in Visual Studio Go to Tools -> NuGet package Manager -> Manage NuGet Packages for Solution then go to the browse tab and search for it.

If you have no particular reason to have the variables serialized in the editor (public) I'd advise the following steps to remove them as public:

  1. Use JsonUtility and serialize your class to json when you've set all values and print it.

.

var json = JsonUtility.ToJson(packsInfo);
Debug.Log(json);
  1. Now, when you start your game the class will be displayed in your console, you can then copy that json and save it in a text file, for example "MyFile.txt"

  2. Add that text file to the project and load it to your game with any of the following methods:

    • Make a public field for it and drag the file to that field:

      public TextAsset packInfoAsset;

    • Add it to a folder called Resources and then use the following code to get the file:

      var packInfoAsset = Resources.Load("MyFile"); // Note that there is no file-ending (.txt)

  3. And finally, deserializing the json to your previous object, so when you load the class, in your Start-method or so, you do:

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

And there you go, you've loaded data from a file instead of having it in the editor.

You can save the data to ScriptableObject which can be stored as asset.

Firstly, wrap your array with a ScriptableObject class:

using UnityEngine;
using System.Collections;

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

And then create an editor script to generate the ScriptableObject from Unity editor menu.

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;
    }
}

In this case, I create the asset based on a json file. If you like fill them manually in Unity Editor, you can also assign your array to the PackInfo object.

When you want to use the data, you can just declare a PackInfo variable:

public class something: MonoBehaviour
{
    public PacksInfo packsInfo;
}

And then drag the ScriptableObject asset you generated directly from Unity editor to the variable in inspector.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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