查看: 598|回复: 0
打印 上一主题 下一主题

[其他] Unity4.x中模仿Unity5资源打包方式(转载)

[复制链接]
may    

8830

主题

80

听众

7万

积分

首席设计师

Rank: 8Rank: 8

纳金币
52304
精华
343

最佳新人 热心会员 灌水之王 活跃会员 突出贡献 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2015-9-26 00:10:08 |只看该作者 |倒序浏览

先简单说一下项目经历 文笔有限别见笑
项目一开始使用的是Unity4.6.1这个版本在进行开发,由于要在ios平台发布一个版本,公司准备购买unity llisences 当时决定买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啦

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
using System.Text;
using System.IO;

public class AssetBundlesTest {

    [MenuItem("Editor/AssetBundle/Export")]
    static void Export(){
        Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
        foreach(Object obj in objs){
            DependLink link = SelectDependencies(obj);
            ExportByDependLink(link);           
        }
        Debug.Log("Export Completed!");
        AssetDatabase.Refresh();
    }

    [MenuItem("Editor/AssetBundle/CleanLabel")]
    static void CleanLabel(){
        Object[] objs = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
        foreach (Object obj in objs){
            AssetDatabase.ClearLabels(obj);
        }
        AssetDatabase.Refresh();
    }

    /*
     *导出资源
     */
    static void ExportByDependLink(DependLink link){
        Export(link);        
    }

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

    /*
     *递归导出
     */
    static void Export(DependLink link){
        BuildPipeline.PushAssetDependencies();
        List<Object> objs = new List<Object>();
        foreach(string asset in link.assets){
            objs.Add(AssetDatabase.LoadAssetAtPath(asset,typeof(Object)));
        }
        // 如果没有目录就先创建
        string path = Application.streamingAssetsPath +"/" + link.label + ".assetbundle";
        int idx = path.LastIndexOf("/");
        string filepath = path.Substring(0, idx);
        if (!Directory.Exists(filepath)){
            Directory.CreateDirectory(filepath);
        }
        BuildPipeline.BuildAssetBundle(null, objs.ToArray(), path, vars);

        if(link.berefs != null && link.berefs.Count > 0){
            foreach(DependLink dlink in link.berefs){
                Export(dlink);
            }
        }        
        BuildPipeline.PopAssetDependencies();
    }

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

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

        // 依赖标签分类
        string[] dependencies = AssetDatabase.GetDependencies(new string[] { AssetDatabase.GetAssetPath(assetObject)});// 找出依赖关系
        if (dependencies.Length != 1){
            foreach(string assetpath in dependencies){
                Object asset = AssetDatabase.LoadAssetAtPath(assetpath, typeof(Object));
                if (asset != assetObject){
                    string[] dlabels = AssetDatabase.GetLabels(asset);
                    if (dlabels.Length != 0){
                        AddAssetByLabel(dlabels[0].ToLower(), assetpath, labelDicts);
                    }else{
                        AddAssetByLabel(rootlabel, assetpath, labelDicts);
                    }
                }               
            }
        }
        //Print(labelDicts);

        // 确定依赖关系
        Dictionary<string, List<string>> relationships = new Dictionary<string, List<string>>();
        List<string> list;
        Object temp;
        string[] templabels;
        string templab;
        foreach (string label in labelDicts.Keys){
            list = labelDicts[label];
            foreach(string asset in list){
                string[] deps = AssetDatabase.GetDependencies(new string[] {asset});
                if (deps.Length > 1){// 有依赖
                    foreach(string dep in deps){
                        if (!dep.Equals(asset)){// 排除自己
                            temp = AssetDatabase.LoadAssetAtPath(dep,typeof(Object));
                            templabels = AssetDatabase.GetLabels(temp);
                            templab = templabels[0].ToLower();
                            if (!templab.Equals(label)){// 不能自己依赖自己
                                AddAssetByLabel(label, templab, relationships);
                            }
                        }
                    }
                }
            }
        }
        Print(relationships);

        // Test
        /*relationships.Clear();
        AddAssetByLabel("A", "B", relationships);
        AddAssetByLabel("A", "C", relationships);
        AddAssetByLabel("A", "D", relationships);

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


        // 过滤重复关系
        List<string> repeates = new List<string>();
        foreach (string label in relationships.Keys){
            List<string> deps = relationships[label];
            foreach(string dept2 in deps){
                bool b = IsRepeated(dept2,relationships,deps);
                Debug.Log("dept2:"+dept2+","+b);
                if(b){
                    repeates.Add(dept2);
                }
            }
            if (repeates.Count > 0){
                foreach(string del in repeates){
                    deps.Remove(del);
                }
                repeates.Clear();
            }
        }

        Print(relationships);

        // Link
        List<string> refs;
        Dictionary<string, DependLink> berefsDict = new Dictionary<string, DependLink>();
        List<DependLink> links;
        DependLink dependLink;
        List<string> assets;
        foreach (string label in labelDicts.Keys){// fill
            assets = labelDicts[label];           
            AddLink(label, assets.ToArray(), null, berefsDict);

        }
        foreach (string label in labelDicts.Keys){// fill
            refs = FindBeRef(label, relationships);
            if(refs.Count > 0){// 资源被引用过
                dependLink = berefsDict[label];
                links = new List<DependLink>();
                foreach(string beref in refs){
                    links.Add(berefsDict[beref]);
                }
                dependLink.berefs = links;
            }
        }  

        // Find
        DependLink headLink = FindNoneDepend(labelDicts, relationships, berefsDict);
        return headLink;
    }

    static void AddLink(string label, string[] assets, List<DependLink> refs, Dictionary<string, DependLink> berefsDict){
        DependLink dependLink;
        berefsDict.TryGetValue(label, out dependLink);
        if (dependLink == null){
            dependLink = new DependLink(label, assets, refs);
            berefsDict.Add(label, dependLink);
        }
    }

    /*
     *添加资源
     */
    static void AddAssetByLabel(string label, string asset, Dictionary<string, List<string>> labelDicts){
        List<string> list = null;
        labelDicts.TryGetValue(label, out list);
        if (list == null){
            list = new List<string>();
            labelDicts.Add(label, list);
        }
        if (!list.Contains(asset)){
            list.Add(asset);
        }
    }

    /*
     *打印
     */
    static void Print(Dictionary<string, List<string>> labelDicts){
        foreach(string key in labelDicts.Keys){
            Debug.Log("Label:"+key);
            List<string> list = labelDicts[key];
            foreach(string asset in list){
                Debug.Log(asset);
            }
        }
    }

    /*
     *查找被引用关系
     */
    static List<string> FindBeRef(string label,Dictionary<string, List<string>> relationships){
        List<string> refs = new List<string>();
        List<string> temp;
        foreach (string key in relationships.Keys){
            temp = relationships[key];
            if(temp.Contains(label)){
                refs.Add(key);
            }
        }
        return refs;
    }

    /*
     *查找头
     */
    static DependLink FindNoneDepend(Dictionary<string, List<string>> labelDicts, Dictionary<string, List<string>> relationships, Dictionary<string, DependLink> berefsDict){
        DependLink dependLink = null;
        foreach (string key in labelDicts.Keys){
            if (!relationships.ContainsKey(key)){
                dependLink = berefsDict[key];
            }
        }
        return dependLink;
    }

    static bool IsRepeated(string label, Dictionary<string, List<string>> relationships, List<string> list){
        foreach (string lb in list){
            List<string> tempList = null;
            relationships.TryGetValue(lb, out tempList);
            if (tempList != null){
                if (tempList.Contains(label)){
                    return true;
                }else{
                    bool b = IsRepeated(label, relationships,tempList);
                    if(b){
                        return true;
                    }
                }
            }
        }
        return false;
    }
}


数据结构类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
*依赖关系链表
*/
class DependLink
{
    public List<DependLink> berefs;
    public string label;// 标签
    public string[] assets;// 当前资源
    public string mainAsset;// 只有一个资源情况

    public DependLink(string label, string[] assets, List<DependLink> berefs){
        this.label = label;
        this.assets = assets;
        this.berefs = berefs;
    }
}


分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

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

关闭

站长推荐上一条 /1 下一条

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

GMT+8, 2024-5-6 16:55 , Processed in 0.085529 second(s), 29 queries .

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

© 2008-2019 Narkii Inc.

回顶部