ScriptableObject进行序列化

来源:互联网 发布:apache服务器优点 编辑:程序博客网 时间:2024/05/22 13:08

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_EDITORusing UnityEditor;#endifusing 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> ();//创建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)

另外,电脑上和手机上打出来的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 {        }    }}
0 0