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)

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

        }
    }
}

你可能感兴趣的:(Unity3D,AssetBundl)