查看: 1639|回复: 4
打印 上一主题 下一主题

[其他] 游戏资源的导出与加载 (转载)

[复制链接]

2317

主题

54

听众

2万

积分

资深设计师

Rank: 7Rank: 7Rank: 7

纳金币
20645
精华
62

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2014-11-29 05:31:37 |只看该作者 |倒序浏览
AssetBundle的知识官网的API已经介绍的比较详细了。AssetBundle是一个unity3d自带的存储数据的类,他可以把你的游戏资源导出为后缀名为.assetbundle的文件。

这里就要涉及到一个unityEditor中的一个类buildPipeline,它有几个静态方法:[url=]BuildAssetBundle[/url]等等,有过这个类就可以实现导出功能。如果你把一个预设导出成为assetbundle文件后。该预设的组件都是全的,不会没有。下面是我写的导出代码,导出代码:
  1. [MenuItem("AssetBundle/Export AssetBundle")]
  2.     public static void ExportAssetBundle()
  3.     {
  4.         GameObject[] objs = Selection.gameObjects;
  5.         for (int iter = 0; iter < objs.Length; ++iter)
  6.         {
  7.             GameObject obj = objs[iter];
  8.             Object prefab = PrefabUtility.GetPrefabParent(obj);
  9.             obj = (GameObject)PrefabUtility.InstantiatePrefab(prefab);
  10.             GameObject prefabObj = _GetClonePrefab(obj) as GameObject;
  11.             _ExportProtocol(prefabObj);
  12.             _Export(prefabObj);
  13.         }
  14.     }

  15.     static void _ExportProtocol(GameObject go)
  16.     {
  17.         UIProtocolList protocoList = new UIProtocolList();
  18.         protocoList.RootName = go.name;
  19.         _TakeOffUIData(go, protocoList);
  20.         ExportProtocol(protocoList);
  21.     }

  22.     static void _TakeOffUIData(GameObject go, UIProtocolList list)
  23.     {
  24.         _SaveObjectInformation(go, list);
  25.         for (int iter = 0; iter < go.transform.childCount; ++iter)
  26.         {
  27.             _TakeOffUIData(go.transform.GetChild(iter).gameObject, list);
  28.         }
  29.     }

  30.     static void _SaveObjectInformation(GameObject go, UIProtocolList list)
  31.     {
  32.         UISprite sprite = go.GetComponent<UISprite>();
  33.         if (sprite != null)
  34.         {
  35.             UIProcotol procotol = new UIProcotol();
  36.             procotol.Name = sprite.spriteName;
  37.             procotol.Template = sprite.atlas.name;
  38.             procotol.Type = (byte)ExportType.SPRITE;
  39.             procotol.Hierarchy = _GetChildHierarchy(go);
  40.             sprite.atlas = null;
  41.             list.ProcotolList.Add(procotol);
  42.         }
  43.         //other type....
  44.         //.....................
  45.     }

  46.     static string _GetChildHierarchy(GameObject go)
  47.     {
  48.         if (go == null)
  49.         {
  50.             return string.Empty;
  51.         }

  52.         Transform parent = go.transform;
  53.         string hierarchy = "\\";
  54.         while (parent != null)
  55.         {
  56.             for (int iter = 0; iter < parent.childCount; ++iter)
  57.             {
  58.                 GameObject obj = parent.GetChild(iter).gameObject;
  59.                 if (object.ReferenceEquals(go, obj))
  60.                 {
  61.                     hierarchy += "/" + iter.ToString();
  62.                     break;
  63.                 }
  64.             }
  65.             go = parent.gameObject;
  66.             parent = parent.transform.parent;
  67.         }
  68.         hierarchy += "\\";
  69.         return hierarchy;
  70.     }

  71.     static void ExportProtocol(UIProtocolList list)
  72.     {
  73.         MemoryStream stream = UIProtocolList.Serialize(list);
  74.         stream.Position = 0;
  75.         System.Byte[] datas = new byte[stream.Length];
  76.         BlodStream blod = ScriptableObject.CreateInstance<BlodStream>();
  77.         stream.Read(datas, 0, datas.Length);
  78.         blod.LoadDatas(datas);
  79.         string path = "Assets/blod.asset";
  80.         AssetDatabase.CreateAsset(blod, path);
  81.         Object o = AssetDatabase.LoadAssetAtPath(path, typeof(BlodStream));
  82.         BuildPipeline.BuildAssetBundle(o, null, "assetbundle/" + list.RootName + "protocol.assetbundle", BuildAssetBundleOptions.CollectDependencies);
  83.         AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(o));
  84.     }

  85.     static void _Export(GameObject prefab)
  86.     {
  87.         List<Object> objs = new List<Object>();
  88.         objs.Add(prefab);
  89.         BuildPipeline.BuildAssetBundle(null, objs.ToArray(), "assetbundle/" + prefab.name + ".assetbundle", BuildAssetBundleOptions.CollectDependencies);
  90.         AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(prefab));

  91.     }

  92.     static Object _GetClonePrefab(GameObject go)
  93.     {
  94.         Object tempPrefab = PrefabUtility.CreateEmptyPrefab("Assets/" + go.name + ".prefab");
  95.         tempPrefab = PrefabUtility.ReplacePrefab(go, tempPrefab);
  96.         Object.DestroyImmediate(go);
  97.         return tempPrefab;
  98.     }
复制代码
这里段代码的目的是导出在场景中的预设,想一下,假设你在做一个UI界面,你做完了,要把它导出,你可以执行这段代码。他会在中间过程中生成一个原预设的Clone,在这个Clone会出现在Hierarchy层中,再在Assets目录下创建一个空预设,把Clone的预设付到空预设,再删除Clone,那么对这个在Assets下预设的操作就不会影响到最原来的预设了。

因为NGUI中导出包含图片的资源后,会变得很大,主要原因Altas是把一张张图片组合成一张大图,你要导出一张图时,是一整张导出的,所以这么大。我的解决方法是导出把他们的altas,sprite变为空,这些altas,sprite的节点位子,信息,记录都放在另外一个asstbundle文件里。信息比如当前包含altas或sprite的游戏物体所在整个游戏物体的索引,还有该组件的类型,还有altas,sprite的名字等信息。我这里自己定义了两个类一个是UIProtocolList,UIProcotol.
  1. public enum ExportType
  2. {
  3.     ATLAS,
  4.     FONT,
  5.     TEXTURE,
  6.     SPRITE
  7. }

  8. [Serializable]
  9. public class UIProcotol
  10. {
  11.     public string Name;
  12.     public string Template;
  13.     public string Hierarchy;
  14.     public byte Type;
  15. }
复制代码
  1. [Serializable]
  2. public class UIProtocolList
  3. {
  4.     public string RootName;
  5.     public List<UIProcotol> ProcotolList = new List<UIProcotol>();

  6.     public static MemoryStream Serialize(UIProtocolList list)
  7.     {
  8.         MemoryStream stream = new MemoryStream();
  9.         BinaryFormatter b = new BinaryFormatter();
  10.         b.Serialize(stream, list);
  11.         return stream;
  12.     }

  13.     public static UIProtocolList Dserialize(MemoryStream stream)
  14.     {
  15.         UIProtocolList list = new UIProtocolList();
  16.         BinaryFormatter b = new BinaryFormatter();
  17.         list = b.Deserialize(stream) as UIProtocolList;
  18.         return list;
  19.     }

  20. }
复制代码
UIProcotol这个类是来表示单个Altas或是其他,UIProtocolList是表示该游戏物体所有的Altas或其他资源。这两个类都是序列化类。为了加载他们时反序列话回来使用。如果要导出为assetbundle文件的自己定义类型类的文件的话,那个类必须继承ScriptableObject。如果不这样Unity3D会报错的。我写了一个类似流一样的类:
  1. public class BlodStream : ScriptableObject
  2. {
  3.     public Byte[] Datas { get { return _Datas; } }

  4.     public void LoadFile(string fileName)
  5.     {
  6.         if (!File.Exists(fileName))
  7.         {
  8.             Debug.Log("the file is empty");
  9.             return;
  10.         }

  11.         FileStream br = File.Open(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
  12.         if (br == null)
  13.         {
  14.             return;
  15.         }
  16.         _Datas = new Byte[br.Length];
  17.         br.Read(_Datas, 0, _Datas.Length);
  18.     }

  19.     public void SaveFile(string fileName)
  20.     {
  21.         FileStream bw = File.Create(fileName);
  22.         if (bw != null)
  23.         {
  24.             bw.Write(_Datas, 0, _Datas.Length);
  25.             bw.Close();
  26.         }
  27.     }

  28.     public void LoadDatas(Byte[] datas)
  29.     {
  30.         _Datas = datas;
  31.     }

  32.     public byte[] _Datas;
  33. }
复制代码
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

hyui    

1

主题

2

听众

6671

积分

高级设计师

Rank: 6Rank: 6

纳金币
2715
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

沙发
发表于 2014-11-29 17:16:27 |只看该作者
very good code share
回复

使用道具 举报

0

主题

2

听众

1346

积分

助理设计师

Rank: 4

纳金币
505
精华
0
板凳
发表于 2014-11-30 11:33:06 |只看该作者
顶一个! ! 谢谢指导! 还在学习...尚未完全理解
回复

使用道具 举报

6

主题

1

听众

1473

积分

助理设计师

Rank: 4

纳金币
126
精华
1
地板
发表于 2014-11-30 15:02:34 |只看该作者
非常感谢分享宝贵经验!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-6-7 09:00 , Processed in 0.089747 second(s), 31 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部