- 最后登录
- 2016-8-29
- 注册时间
- 2012-8-25
- 阅读权限
- 90
- 积分
- 23585
- 纳金币
- 20645
- 精华
- 62
|
AssetBundle的知识官网的API已经介绍的比较详细了。AssetBundle是一个unity3d自带的存储数据的类,他可以把你的游戏资源导出为后缀名为.assetbundle的文件。
这里就要涉及到一个unityEditor中的一个类buildPipeline,它有几个静态方法:[url=]BuildAssetBundle[/url]等等,有过这个类就可以实现导出功能。如果你把一个预设导出成为assetbundle文件后。该预设的组件都是全的,不会没有。下面是我写的导出代码,导出代码:- [MenuItem("AssetBundle/Export AssetBundle")]
- public static void ExportAssetBundle()
- {
- GameObject[] objs = Selection.gameObjects;
- for (int iter = 0; iter < objs.Length; ++iter)
- {
- GameObject obj = objs[iter];
- Object prefab = PrefabUtility.GetPrefabParent(obj);
- obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
- GameObject prefabObj = _GetClonePrefab(obj) as GameObject;
- _ExportProtocol(prefabObj);
- _Export(prefabObj);
- }
- }
- static void _ExportProtocol(GameObject go)
- {
- UIProtocolList protocoList = new UIProtocolList();
- protocoList.RootName = go.name;
- _TakeOffUIData(go, protocoList);
- ExportProtocol(protocoList);
- }
- static void _TakeOffUIData(GameObject go, UIProtocolList list)
- {
- _SaveObjectInformation(go, list);
- for (int iter = 0; iter < go.transform.childCount; ++iter)
- {
- _TakeOffUIData(go.transform.GetChild(iter).gameObject, list);
- }
- }
- static void _SaveObjectInformation(GameObject go, UIProtocolList list)
- {
- UISprite sprite = go.GetComponent<UISprite>();
- if (sprite != null)
- {
- UIProcotol procotol = new UIProcotol();
- procotol.Name = sprite.spriteName;
- procotol.Template = sprite.atlas.name;
- procotol.Type = (byte)ExportType.SPRITE;
- procotol.Hierarchy = _GetChildHierarchy(go);
- sprite.atlas = null;
- list.ProcotolList.Add(procotol);
- }
- //other type....
- //.....................
- }
- static string _GetChildHierarchy(GameObject go)
- {
- if (go == null)
- {
- return string.Empty;
- }
- Transform parent = go.transform;
- string hierarchy = "\\";
- while (parent != null)
- {
- for (int iter = 0; iter < parent.childCount; ++iter)
- {
- GameObject obj = parent.GetChild(iter).gameObject;
- if (object.ReferenceEquals(go, obj))
- {
- hierarchy += "/" + iter.ToString();
- break;
- }
- }
- go = parent.gameObject;
- parent = parent.transform.parent;
- }
- hierarchy += "\\";
- return hierarchy;
- }
- static void ExportProtocol(UIProtocolList list)
- {
- MemoryStream stream = UIProtocolList.Serialize(list);
- stream.Position = 0;
- System.Byte[] datas = new byte[stream.Length];
- BlodStream blod = ScriptableObject.CreateInstance<BlodStream>();
- stream.Read(datas, 0, datas.Length);
- blod.LoadDatas(datas);
- string path = "Assets/blod.asset";
- AssetDatabase.CreateAsset(blod, path);
- Object o = AssetDatabase.LoadAssetAtPath(path, typeof(BlodStream));
- BuildPipeline.BuildAssetBundle(o, null, "assetbundle/" + list.RootName + "protocol.assetbundle", BuildAssetBundleOptions.CollectDependencies);
- AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(o));
- }
- static void _Export(GameObject prefab)
- {
- List<Object> objs = new List<Object>();
- objs.Add(prefab);
- BuildPipeline.BuildAssetBundle(null, objs.ToArray(), "assetbundle/" + prefab.name + ".assetbundle", BuildAssetBundleOptions.CollectDependencies);
- AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(prefab));
- }
- static Object _GetClonePrefab(GameObject go)
- {
- Object tempPrefab = PrefabUtility.CreateEmptyPrefab("Assets/" + go.name + ".prefab");
- tempPrefab = PrefabUtility.ReplacePrefab(go, tempPrefab);
- Object.DestroyImmediate(go);
- return tempPrefab;
- }
复制代码 这里段代码的目的是导出在场景中的预设,想一下,假设你在做一个UI界面,你做完了,要把它导出,你可以执行这段代码。他会在中间过程中生成一个原预设的Clone,在这个Clone会出现在Hierarchy层中,再在Assets目录下创建一个空预设,把Clone的预设付到空预设,再删除Clone,那么对这个在Assets下预设的操作就不会影响到最原来的预设了。
因为NGUI中导出包含图片的资源后,会变得很大,主要原因Altas是把一张张图片组合成一张大图,你要导出一张图时,是一整张导出的,所以这么大。我的解决方法是导出把他们的altas,sprite变为空,这些altas,sprite的节点位子,信息,记录都放在另外一个asstbundle文件里。信息比如当前包含altas或sprite的游戏物体所在整个游戏物体的索引,还有该组件的类型,还有altas,sprite的名字等信息。我这里自己定义了两个类一个是UIProtocolList,UIProcotol.- public enum ExportType
- {
- ATLAS,
- FONT,
- TEXTURE,
- SPRITE
- }
- [Serializable]
- public class UIProcotol
- {
- public string Name;
- public string Template;
- public string Hierarchy;
- public byte Type;
- }
复制代码- [Serializable]
- public class UIProtocolList
- {
- public string RootName;
- public List<UIProcotol> ProcotolList = new List<UIProcotol>();
- public static MemoryStream Serialize(UIProtocolList list)
- {
- MemoryStream stream = new MemoryStream();
- BinaryFormatter b = new BinaryFormatter();
- b.Serialize(stream, list);
- return stream;
- }
- public static UIProtocolList Dserialize(MemoryStream stream)
- {
- UIProtocolList list = new UIProtocolList();
- BinaryFormatter b = new BinaryFormatter();
- list = b.Deserialize(stream) as UIProtocolList;
- return list;
- }
- }
复制代码 UIProcotol这个类是来表示单个Altas或是其他,UIProtocolList是表示该游戏物体所有的Altas或其他资源。这两个类都是序列化类。为了加载他们时反序列话回来使用。如果要导出为assetbundle文件的自己定义类型类的文件的话,那个类必须继承ScriptableObject。如果不这样Unity3D会报错的。我写了一个类似流一样的类:- public class BlodStream : ScriptableObject
- {
- public Byte[] Datas { get { return _Datas; } }
- public void LoadFile(string fileName)
- {
- if (!File.Exists(fileName))
- {
- Debug.Log("the file is empty");
- return;
- }
- FileStream br = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
- if (br == null)
- {
- return;
- }
- _Datas = new Byte[br.Length];
- br.Read(_Datas, 0, _Datas.Length);
- }
- public void SaveFile(string fileName)
- {
- FileStream bw = File.Create(fileName);
- if (bw != null)
- {
- bw.Write(_Datas, 0, _Datas.Length);
- bw.Close();
- }
- }
- public void LoadDatas(Byte[] datas)
- {
- _Datas = datas;
- }
- public byte[] _Datas;
- }
复制代码 |
|