Unity学习笔记--实现一个简单的序列化反序列化工具

前言

最近需要实现一个序列化反序列化工具,由于数据不是很复杂,所以自己实现一个简单的工具

设计

  1. 首先得有一个数据类,比如PlayerData
  2. PlayerData里面存储具体需要存储的数据类,比如需要存储Player身上一些碰撞体的数据,刚体的数据等等。
  3. 数据有了之后,我们就需要序列化工具了,比如叫做DataSerializeHelper,它负责序列化传过来的数据
  4. 我们还需要一个写入文件的类,比如叫做DataFileUtility,它负责把传过来的字符串写入到指定文件中

代码

public class PlayerData
{
    
    
    public string[] rb_data {
    
     get; set; }//比如[mass, drag] (按照自己的规则就好了)
    private DataSerializeHelper serialize_helper;

    private const string rb_data_key = "rb_data";
    
    public PlayerData()
    {
    
    
        serialize_helper = new DataSerializeHelper();
    }
    
    public void Serialize(string file_path)
    {
    
    
        File.WriteAllText(file_path, "");//先清空
        string rb_data_content = serialize_helper.Serialize(rb_data);
        DataFileUtility.Append(file_path, rb_data_content, rb_data_key);
    }
    
    public void Deserialize(string file_content)
    {
    
    
        serialize_helper.DeSerialize(file_content);
        rb_data = serialize_helper.GetListByKey(rb_data_key);
    }
}


public class DataSerializeHelper
{
    
    
    private string SPLIT_SIGN = ",";
    private Dictionary<string, string[]> kv_dict = new Dictionary<string, string[]>();
    
    //需要在调用DeSerialize之后才有用
    public string[] GetListByKey(string key)
    {
    
    
        return kv_dict.ContainsKey(key) ? kv_dict[key] : new string[0];
    }
    
    public string Serialize(string[] list)
    {
    
    
        StringBuilder sb = new StringBuilder();
        foreach (string data in list)
        {
    
    
            sb.Append(data).Append(SPLIT_SIGN);
        }
        if (sb.Length > 0)
        {
    
    
            sb.Remove(sb.Length - 1, 1);//去掉最后一个SPLIT_SIGN
        }
        return sb.ToString();
    }
    
    public void DeSerialize(string content)
    {
    
    
        if (content.Equals("")) return;
        //由于content直接从文件读取,并且文件最后一行是空的,所以得删除最后一个元素
        DeSerialize((content.Remove(content.Length - 1)).Split("\n"));
    }
    
    public void DeSerialize(string[] contents)
    {
    
    
        for (int i = 0, step = 2; i < contents.Length; i += step)
        {
    
    
            string key = contents[i];
            string[] value = contents[i + 1].Split(SPLIT_SIGN);
            //如果key为空并且内容也为空,则不加入字典
            if (!key.Equals("") && !contents[i + 1].Equals(""))
            {
    
    
                kv_dict.Add(key, value);
            }
        }
    }
    
}


public static class DataFileUtility
{
    
    

    public static void Write(string file_path, string content, string key)
    {
    
    
        string res_content = key + "\n" + content + '\n';
        File.WriteAllText(file_path, res_content);
    }
    
    public static void Append(string file_path, string content, string key)
    {
    
    
        if (!File.Exists(file_path))
        {
    
    
            Write(file_path, content, key);
        }
        else
        {
    
    
            string res_content = key + "\n" + content + '\n';
            File.AppendAllText(file_path, res_content);
        }
    }
    
    public static string[] ReadAllLines(string file_path)
    {
    
    
        return File.Exists(file_path) ? File.ReadAllLines(file_path) : null;
    }
    
    public static string ReadAllText(string file_path)
    {
    
    
        return File.Exists(file_path) ? File.ReadAllText(file_path) : null;
    }
    
}
public void Serialize()
{
    
    
	PlayerData data = new PlayerData();
	data.rb_data = new string[] {
    
    10, 10};//mass, drag
	string file_path = "player_data.txt";
	data.Serialize(data);
}

public void Deserialize()
{
    
    
	PlayerData data = new PlayerData();
	string file_path = "player_data.txt";
	data.Deserialize(data);
	print(data.rb_data);
}

总结

如果想加数据,直接在数据类里面加一个成员变量和对应的key值就好了,不需要修改内部的代码
只是需要在外部拿取string数组里面的数据,然后根据自己的规则,做自己的事就好了(比如赋值等等)。

预告

下篇文章将讨论下我在Unity中具体使用怎么使用JsonUtility存储数据以及踩到的一些坑

猜你喜欢

转载自blog.csdn.net/qq_52855744/article/details/128798731