Unity中数据序列化

Unity实际开发中,一般会有很多个场景,不可能每次都在setting里加场景号,我们需要动态加载。一般的做法是把这些场景做成一个一个prefab,再把场景信息保存起来。然后切换场景的时候切到一个预先保持的空场景里 保存一个空的场景,在加载之前保持的prefab,在对场景信息赋值。这里的场景信息可能包括渲染设置,lightmap等内容。这时候需要把这些场景信息保存起来。在c#中很容易对一些数据序列化。
一.用c#的BinaryFormatter对数据进行二进制序列化
例:
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;
[Serializable] //自定义的类一定要加这个特性
public class Person
{
	public string name = "";
	public int age = 0;
}


public class Test
{
	static List m_persons = new List();
	static void init()
	{
		for (int i = 0; i < 100; i++)
		{
			Person p = new Person();
			p.name = "test"+i;
			p.age = i;
			m_persons.Add(p);
		}
	}
	//序列化
	static void serialize()
	{
		FileStream writer = new FileStream("./data.dat", FileMode.Create);            
		try
		{
			BinaryFormatter binaryFormat = new BinaryFormatter();
			binaryFormat.Serialize(writer, m_persons);
		}
		catch (SerializationException e)
		{
			ClientLog.LogError("Failed to serilize. " + e.Message);
		}
		finally
		{
			writer.Close();
		}
	}
	//反序列化
	static void deserialize()
	{
		List listData = null;
		FileStream reader = new FileStream("./data.dat", FileMode.Open);
		try
		{
			BinaryFormatter binaryFormat = new BinaryFormatter();
			listData = (List)binaryFormat.Deserialize(reader);
		}
		catch (SerializationException e)
		{
			ClientLog.LogError("Failed to Deserialize:" + e.Message);
		}
		finally
		{
			reader.Close();
		}
	}
}
上面的方法可以序列化自定义类型的数据,而且像List、Dictionary这种实现了ISerializable接口的都可以用这种方法序列化。但在unity中这不是最好的方法。


二.用unity的ScriptableObject序列化
这种方法,unity的一些类型以及c#的基础类型都可以序列化,因此在unity中建议用这种方法。
例如自定义数据类型如下(注意:要序列化的类型一定要继承ScriptableObject,一定要放在单独的文件里):
public class Test : ScriptableObject
{
	public string name = "this is a test!";
	[Serializable] //自定义的类一定要加这个特性
	public class T
	{
		public Vector4 m_v = new Vector4(1.0f, 1.0f, 1.0f, 1.0f);
	}
	public T m_t;
}
然后再unity添加菜单选项:
[MenuItem("Tools/Save Data")]
static public void SerializeData()
{
	Test test = ScriptableObject.CreateInstance();
	string destPath = "Assets/StreamingAssets/test.asset";
	AssetDatabase.CreateAsset(test, destPath); //生成序列化数据
    AssetDatabase.Refresh();
	
	Object o = AssetDatabase.LoadAssetAtPath(destPath, typeof(LightmapInfo));
	string bundlePath = "Assets/StreamingAssets/test.bundle";    
	BuildPipeline.BuildAssetBundle(o, null, bundlePath, BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies, BuildTarget.StandaloneWindow);
    AssetDatabase.DeleteAsset(destPath);
}
生成序列化数据,然后打成bundle包就可以用WWW加载了。
反序列化如下:
IEnumerator DeserializeData()
{
	string bundlePath = "Assets/StreamingAssets/test.bundle"; 
	WWW www = new WWW(bundlePath);
	yield return www;
	
	Test test = assetBundle.mainAsset as Test;
	Debug.Log(test.name);
	Debug.Log(test.m_t.x);
}

你可能感兴趣的:(Unity)