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 {}
}
}
推荐阅读
- Unity3d|Unity中的层级以及渲染顺序
- Unity3D|Character Joint 角色关节
- Unity使用NetworkServer与NetWorkClient实现服务端与客户端传递消息
- Unity3D|unity3d中布娃娃系统
- 知识点|简单应用 - 在unity使用ScriptableObject制作配置文件