Unity3D|ScriptableObject进行序列化

ScriptableObject一般用来存储u3d无法打包的对象(object),利用它可以将对象打包为assetbundle或者.assets文件以供后续使用。总体来看这也是一个很好的序列化方法。
Test.cs类,继承ScriptableObject 用来表示要要存储的对象原型

using UnityEngine; using UnityEditor; public class Test : ScriptableObject { public string testString; public int testInt; public Vector3 testVector3; public AudioClip testAudioClip; public GameObject testGameObject; public void PrintTest() { Debug.Log("这是一个类"); } }

2.创建一个编辑器脚本,用来对此类的实例进行打包
TestEditor.cs
using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif using System.Collections.Generic; namespace ss{ public class TestEditor { #if UNITY_EDITOR [MenuItem("Assets/Export Test Object")] public static void Execute() { Test test = ScriptableObject.CreateInstance (); //创建Test的一个实例 //下面5句是设置test对象的属性 test.testString = "Test String"; test.testInt=100; test.testVector3 = new Vector3 (1, 1, 1); test.testGameObject=Resources.Load("Cube")as GameObject; //从指定文件夹下加载一个GameObject类型的Object作为test对象的一个字段值 test.testAudioClip=Resources.Load("music_source")as AudioClip; //从指定文件夹下加载一个AudioClip类型的Object作为test对象的一个字段值//test.testGameObject=GameObject.CreatePrimitive(PrimitiveType.Cube); //这种方式可以动态创建游戏对象 AssetDatabase.CreateAsset(test , "Assets/TestAsset.asset" ); //创建资源文件,这时会在监视面板中看到并且可以直接编辑数据啦!!!! AssetDatabase.Refresh(); //重新导入有更新的资源。//我们还可以创建资源包Object o = AssetDatabase.LoadAssetAtPath("Assets/TestAsset.asset", typeof(Test)); //重新获取上面我们创建的的Asset资源 string targetPath = Application.dataPath + "/StreamingAssets/" + o.name + ".unity3d"; // Application.dataPath包含游戏数据的路径,在Unity中指Assets目录 Debug.Log( Application.dataPath); Debug.Log (targetPath); bool a = BuildPipeline.BuildAssetBundle(o,null, targetPath, BuildAssetBundleOptions.CollectDependencies); //打AssetBundle资源包 if (a) { Debug.Log("资源打包成功"); } else { Debug.Log("资源打包失败"); } AssetDatabase.Refresh(); //重新导入有更新的资源。 //到此我们已经创建了名为“TestAsset”的资源文件了,需要用到的时候有三种方法: //1.编辑器环境下使用的话可以用Test o = AssetDatabase.LoadAssetAtPath(path , typeof(Test)); 将此资源文件“反序列化"为一个类对象,从而可以进行后续操作 //2.运行时使用可以将该资源文件放到Resources文件夹下,并通过Test o = Resourecs.Load("TestAsset",typeof(Test)) as Test; 也可以通过WWW来 加载,详细请参考Unity3DAPI //我们还可以将其打包为asset,BuildPipeline.BuildAssetBundle(test, null, "TestAsset.assetbundle"); 若如此则只能通过WWW来加载 } #endif } }

AssetBundle 最核心的方法其实就它:
BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)

参数1:它只能放一个对象,因为我们这里是分别打包,所以通过循环将 每个对象分别放在了这里。
参数2:可以放入一个数组对象。
默认情况下打的包只能在电脑上用,如果要在手机上用就要添加一个参数。
Android上:
BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.Android);

IOS上:
BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.iPhone)

【Unity3D|ScriptableObject进行序列化】另外,电脑上和手机上打出来的Assetbundle不能混用,不同平台只能用自己的。
Create AssetBundles All:将所有对象打包在一个Assetbundle中。
using UnityEngine; using UnityEditor; using System.Collections; public class NewBehaviourScript : MonoBehaviour {[MenuItem("Custom Editor/Create AssetBunldes Main")] static void CreateAssetBunldesMain () { //获取在Project视图中选择的所有游戏对象 Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets); //返回通过类型和选择模式过滤的当前选择的物体。 //SelectionMode 选择模式(Deep:返回选择和所有选择的子变换。ExcludePrefab:从选择中排除任何预制。Editable:排除任何对象不得修改。Assets:仅返回资源目录中的资源对象。DeepAssets:如果选择包含文件夹,也包含所有资源和子目录。)//遍历所有的游戏对象 foreach (Object obj in SelectedAsset) { string sourcePath = AssetDatabase.GetAssetPath (obj); //本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径 //StreamingAssets是只读路径,不能写入 //服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。 string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle"; if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)) { Debug.Log(obj.name +"资源打包成功"); } else { Debug.Log(obj.name +"资源打包失败"); } } AssetDatabase.Refresh (); //刷新编辑器//最核心的方法其实就它: //BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies) //参数1:它只能放一个对象,因为我们这里是分别打包,所以通过循环将每个对象分别放在了这里。 //参数2:可以放入一个数组对象。 //默认情况下打的包只能在电脑上用,如果要在手机上用就要添加一个参数。 //Android上:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.Android) //IOS上:BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies,BuildTarget.iPhone) //另外,电脑上和手机上打出来的Assetbundle不能混用,不同平台只能用自己的。 //Create AssetBundles All:将所有对象打包在一个Assetbundle中。 }[MenuItem("Custom Editor/Create AssetBunldes ALL")] static void CreateAssetBunldesALL () {Caching.CleanCache (); string Path = Application.dataPath + "/StreamingAssets/ALL.assetbundle"; Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets); //DeepAssets:如果选择包含文件夹,也包含所有资源和子目录。foreach (Object obj in SelectedAsset) { Debug.Log ("Create AssetBunldes name :" + obj); }//这里注意第二个参数就行 if (BuildPipeline.BuildAssetBundle (null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies)) { AssetDatabase.Refresh (); } else {} } }

    推荐阅读