纳金网

标题: Unity4.x中模仿Unity5资源打包方式 [打印本页]

作者: 王者再临    时间: 2015-10-29 23:43
标题: Unity4.x中模仿Unity5资源打包方式

记录一下在做项目过程中遇到到一些问题,和大家分享一下 第一次发帖。不对的地方望大神们批评指出
先简单说一下项目经历 文笔有限别见笑
项目一开始使用的是Unity4.6.1这个版本在进行开发,由于要在ios平台发布一个版本,公司准备购买unity llisences 当时决定买[color=rgb(85, 85, 85) !important]unity5的lisences。所以决定吧项目升级到Unity5版本,在升级的过程中遇到了各种的坑,各种问题网上基本找不大解决方案。最后只有自己一个个的填坑。最后终于可以发表版本了;但是当时的场景是没有进行资源分离打包的;
由于我们的项目使用了一个叫T4M 的插件 该插件不兼容Unity5 最后google各种外国网站 发现这个T4M插件好像停止对unity5的支持了。最后卡在这里了。

经过开会讨论最后决定吧项目还原到Unity4.6.1这个版本进行开发。折腾呀 说多了都是泪。。。。

最后发现Unity5里面确实优化了很多东西 渲染这块和烘焙这块 还有shader 最让人高兴的就是AssetBundle打包方式给集成到编辑器里面了;回到Unity4版本过后 自己就一直想模仿Unity5的
打包方式。最后终于实现了。

Unity4.6里面每个资源都有个Labels属性  这个我就当成了Unity5里面的inpector里面的assetbundle来使用了
如果想把两个资源打包一起就可以给他相同的labels

比如一个player 的prefab 依赖于材质A 材质A使用了shader
prefab的label设置为 player/player01
材质和贴图设置为相同的labels playermat
最后shader设置labels 为 custom/diffuseshader

打包就OK啦
  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEditor;
  4. using System.Collections.Generic;
  5. using System.Text;
  6. using System.IO;

  7. public class AssetBundlesTest {

  8.     [MenuItem("Editor/AssetBundle/Export")]
  9.     static void Export(){
  10.         Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
  11.         foreach(Object obj in objs){
  12.             DependLink link = SelectDependencies(obj);
  13.             ExportByDependLink(link);           
  14.         }
  15.         Debug.Log("Export Completed!");
  16.         AssetDatabase.Refresh();
  17.     }

  18.     [MenuItem("Editor/AssetBundle/CleanLabel")]
  19.     static void CleanLabel(){
  20.         Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
  21.         foreach (Object obj in objs){
  22.             AssetDatabase.ClearLabels(obj);
  23.         }
  24.         AssetDatabase.Refresh();
  25.     }

  26.     /*
  27.      *导出资源
  28.      */
  29.     static void ExportByDependLink(DependLink link){
  30.         Export(link);        
  31.     }

  32.     /*
  33.      *导出资源选项
  34.      */
  35.     static BuildAssetBundleOptions vars = BuildAssetBundleOptions.CompleteAssets | BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.DeterministicAssetBundle;

  36.     /*
  37.      *递归导出
  38.      */
  39.     static void Export(DependLink link){
  40.         BuildPipeline.PushAssetDependencies();
  41.         List<Object> objs = new List<Object>();
  42.         foreach(string asset in link.assets){
  43.             objs.Add(AssetDatabase.LoadAssetAtPath(asset,typeof(Object)));
  44.         }
  45.         // 如果没有目录就先创建
  46.         string path = Application.streamingAssetsPath +"/" + link.label + ".assetbundle";
  47.         int idx = path.LastIndexOf("/");
  48.         string filepath = path.Substring(0, idx);
  49.         if (!Directory.Exists(filepath)){
  50.             Directory.CreateDirectory(filepath);
  51.         }
  52.         BuildPipeline.BuildAssetBundle(null, objs.ToArray(), path, vars);
  53.         
  54.         if(link.berefs != null && link.berefs.Count > 0){
  55.             foreach(DependLink dlink in link.berefs){
  56.                 Export(dlink);
  57.             }
  58.         }        
  59.         BuildPipeline.PopAssetDependencies();
  60.     }

  61.     /*
  62.      *查找资源
  63.      */
  64.     static DependLink SelectDependencies(Object assetObject){
  65.         string[] labels = AssetDatabase.GetLabels(assetObject);
  66.         if (labels.Length == 0){// 没有标签不打包
  67.             return null;
  68.         }

  69.         // 最顶层
  70.         string rootlabel = labels[0].ToLower();
  71.         Dictionary<string, List<string>> labelDicts = new Dictionary<string, List<string>>();
  72.         AddAssetByLabel(rootlabel, AssetDatabase.GetAssetPath(assetObject), labelDicts);

  73.         // 依赖标签分类
  74.         string[] dependencies = AssetDatabase.GetDependencies(new string[] { AssetDatabase.GetAssetPath(assetObject)});// 找出依赖关系
  75.         if (dependencies.Length != 1){
  76.             foreach(string assetpath in dependencies){
  77.                 Object asset = AssetDatabase.LoadAssetAtPath(assetpath, typeof(Object));
  78.                 if (asset != assetObject){
  79.                     string[] dlabels = AssetDatabase.GetLabels(asset);
  80.                     if (dlabels.Length != 0){
  81.                         AddAssetByLabel(dlabels[0].ToLower(), assetpath, labelDicts);
  82.                     }else{
  83.                         AddAssetByLabel(rootlabel, assetpath, labelDicts);
  84.                     }
  85.                 }               
  86.             }
  87.         }
  88.         //Print(labelDicts);

  89.         // 确定依赖关系
  90.         Dictionary<string, List<string>> relationships = new Dictionary<string, List<string>>();
  91.         List<string> list;
  92.         Object temp;
  93.         string[] templabels;
  94.         string templab;
  95.         foreach (string label in labelDicts.Keys){
  96.             list = labelDicts[label];
  97.             foreach(string asset in list){
  98.                 string[] deps = AssetDatabase.GetDependencies(new string[] {asset});
  99.                 if (deps.Length > 1){// 有依赖
  100.                     foreach(string dep in deps){
  101.                         if (!dep.Equals(asset)){// 排除自己
  102.                             temp = AssetDatabase.LoadAssetAtPath(dep,typeof(Object));
  103.                             templabels = AssetDatabase.GetLabels(temp);
  104.                             templab = templabels[0].ToLower();
  105.                             if (!templab.Equals(label)){// 不能自己依赖自己
  106.                                 AddAssetByLabel(label, templab, relationships);
  107.                             }
  108.                         }
  109.                     }
  110.                 }
  111.             }
  112.         }
  113.         Print(relationships);

  114.         // Test
  115.         /*relationships.Clear();
  116.         AddAssetByLabel("A", "B", relationships);
  117.         AddAssetByLabel("A", "C", relationships);
  118.         AddAssetByLabel("A", "D", relationships);

  119.         AddAssetByLabel("B", "C", relationships);
  120.         AddAssetByLabel("C", "D", relationships);*/


  121.         // 过滤重复关系
  122.         List<string> repeates = new List<string>();
  123.         foreach (string label in relationships.Keys){
  124.             List<string> deps = relationships[label];
  125.             foreach(string dept2 in deps){
  126.                 bool b = IsRepeated(dept2,relationships,deps);
  127.                 Debug.Log("dept2:"+dept2+","+b);
  128.                 if(b){
  129.                     repeates.Add(dept2);
  130.                 }
  131.             }
  132.             if (repeates.Count > 0){
  133.                 foreach(string del in repeates){
  134.                     deps.Remove(del);
  135.                 }
  136.                 repeates.Clear();
  137.             }
  138.         }

  139.         Print(relationships);

  140.         // Link
  141.         List<string> refs;
  142.         Dictionary<string, DependLink> berefsDict = new Dictionary<string, DependLink>();
  143.         List<DependLink> links;
  144.         DependLink dependLink;
  145.         List<string> assets;
  146.         foreach (string label in labelDicts.Keys){// fill
  147.             assets = labelDicts[label];           
  148.             AddLink(label, assets.ToArray(), null, berefsDict);
  149.             
  150.         }
  151.         foreach (string label in labelDicts.Keys){// fill
  152.             refs = FindBeRef(label, relationships);
  153.             if(refs.Count > 0){// 资源被引用过
  154.                 dependLink = berefsDict[label];
  155.                 links = new List<DependLink>();
  156.                 foreach(string beref in refs){
  157.                     links.Add(berefsDict[beref]);
  158.                 }
  159.                 dependLink.berefs = links;
  160.             }
  161.         }  

  162.         // Find
  163.         DependLink headLink = FindNoneDepend(labelDicts, relationships, berefsDict);
  164.         return headLink;
  165.     }

  166.     static void AddLink(string label, string[] assets, List<DependLink> refs, Dictionary<string, DependLink> berefsDict){
  167.         DependLink dependLink;
  168.         berefsDict.TryGetValue(label, out dependLink);
  169.         if (dependLink == null){
  170.             dependLink = new DependLink(label, assets, refs);
  171.             berefsDict.Add(label, dependLink);
  172.         }
  173.     }

  174.     /*
  175.      *添加资源
  176.      */
  177.     static void AddAssetByLabel(string label, string asset, Dictionary<string, List<string>> labelDicts){
  178.         List<string> list = null;
  179.         labelDicts.TryGetValue(label, out list);
  180.         if (list == null){
  181.             list = new List<string>();
  182.             labelDicts.Add(label, list);
  183.         }
  184.         if (!list.Contains(asset)){
  185.             list.Add(asset);
  186.         }
  187.     }

  188.     /*
  189.      *打印
  190.      */
  191.     static void Print(Dictionary<string, List<string>> labelDicts){
  192.         foreach(string key in labelDicts.Keys){
  193.             Debug.Log("Label:"+key);
  194.             List<string> list = labelDicts[key];
  195.             foreach(string asset in list){
  196.                 Debug.Log(asset);
  197.             }
  198.         }
  199.     }

  200.     /*
  201.      *查找被引用关系
  202.      */
  203.     static List<string> FindBeRef(string label,Dictionary<string, List<string>> relationships){
  204.         List<string> refs = new List<string>();
  205.         List<string> temp;
  206.         foreach (string key in relationships.Keys){
  207.             temp = relationships[key];
  208.             if(temp.Contains(label)){
  209.                 refs.Add(key);
  210.             }
  211.         }
  212.         return refs;
  213.     }

  214.     /*
  215.      *查找头
  216.      */
  217.     static DependLink FindNoneDepend(Dictionary<string, List<string>> labelDicts, Dictionary<string, List<string>> relationships, Dictionary<string, DependLink> berefsDict){
  218.         DependLink dependLink = null;
  219.         foreach (string key in labelDicts.Keys){
  220.             if (!relationships.ContainsKey(key)){
  221.                 dependLink = berefsDict[key];
  222.             }
  223.         }
  224.         return dependLink;
  225.     }

  226.     static bool IsRepeated(string label, Dictionary<string, List<string>> relationships, List<string> list){
  227.         foreach (string lb in list){
  228.             List<string> tempList = null;
  229.             relationships.TryGetValue(lb, out tempList);
  230.             if (tempList != null){
  231.                 if (tempList.Contains(label)){
  232.                     return true;
  233.                 }else{
  234.                     bool b = IsRepeated(label, relationships,tempList);
  235.                     if(b){
  236.                         return true;
  237.                     }
  238.                 }
  239.             }
  240.         }
  241.         return false;
  242.     }
  243. }

  244. 数据结构类

  245. using System;
  246. using System.Collections.Generic;
  247. using System.Linq;
  248. using System.Text;

  249. /*
  250. *依赖关系链表
  251. */
  252. class DependLink
  253. {
  254.     public List<DependLink> berefs;
  255.     public string label;// 标签
  256.     public string[] assets;// 当前资源
  257.     public string mainAsset;// 只有一个资源情况

  258.     public DependLink(string label, string[] assets, List<DependLink> berefs){
  259.         this.label = label;
  260.         this.assets = assets;
  261.         this.berefs = berefs;
  262.     }
  263. }
复制代码





欢迎光临 纳金网 (http://go.narkii.com/club/) Powered by Discuz! X2.5