中重度手游项目开发(二) AssetBundle资源与Resources资源无缝接入

        当每次开发项目时,最基础也是最重要的莫过于资源管理了,对于u3d的资源管理,最方便的莫过于通过“配置标志位”来做到资源无缝在AssetBundle与Resources之间切换,如果要做到这个,前期的资源规范就非常重要了,在这里,我将提供一整套完整可用的方案,欢迎大家交流。

        一、方案背景与限制

        在unity3d 5.x中提供了新的AssetBundle打包方案,极大的减轻了AssetBundle的实现难度与维护成本,在新这种新的模式下,有以下2点注意:

        1.每个资源的AssetBundle Lable中,都可以明确的指定资源名称,但是Lable中只能为小写

        2.在每个资源的AssetBundle Lable中,都可以指定层级结构,用"/"隔开,在生成时会在指定目录下按照命名结构进行层级创建,如下图

       生成后,目录结构如下图:

       二、具体方案与对应资源规范

  1. 在游戏中的需要用到的预制件,在开发时,都放入到Resources目录下的指定类型的文件夹内,注意:此目录下的文件夹与资源名称只能是小写字母与'_'的组合,方便统一资源加载
  2. 生成的AssetBundle资源文件放在StreamingAssets目录下,至于发布时是解压到Application.persistentDataPath还是先查找Application.persistentDataPath目录,没有再读取StreamingAssets目录,由项目决定(但是需要注意的是:真机的StreamingAssets目录只能用www方法进行访问
  3. 在标记Resources目录下资源的AssetBundle Lable时,内容为相对于Resources的目录结构+名称,如图所示
  4. 如果有2个或2个以上的Resources目录下预制件引用了同一个资源,需要将此资源独立设置一个AssetBundle Lable(建议根据在Asset目录下的相对目录进行设置,方便统一对比查找)
  5. U3d的一些内置资源默认会放入到最上层的AssetBundle包中,如果对冗余资源介意的话,需要把内置资源也生成为对应的依赖包

        三、工具与代码范例(在unity3d 5.6.6下运行通过)

    1.自动打包工具代码(里面的目录、平台大家可以根据实际情况进行替换,代码功能比较单一且插入代码的插件实在太搓了,我就去掉注释了)

    [MenuItem("tool/creat asset")]
    static void creatAsset()
    {
        Dictionary<string, int> m_pathAndTime = new Dictionary<string, int>();
        List<GameObject> m_resObj = new List<GameObject>();
        string m_countPath = "Effect/";
        Object[] prefableArr = Resources.LoadAll(m_countPath);
        if(prefableArr.Length == 0)
        {Application.persistentDataPath }
        else
        {
            for (int i = 0; i < prefableArr.Length; i++)
            {
                string tmpPath = AssetDatabase.GetAssetPath(prefableArr[i]);
                string[] ObjPath = AssetDatabase.GetDependencies(tmpPath);
                if(ObjPath.Length == 0)
                { }
                else
                {
                    for (int j = 0; j < ObjPath.Length; j++)
                    {
                        if (ObjPath[j].StartsWith("Assets/Resources"))
                        { continue; }
                        else
                        {
                            string name = ObjPath[j].Replace("Assets/", "");
                            int count = 0;
                            if (m_pathAndTime.TryGetValue(name, out count))
                            { m_pathAndTime[name] += 1; }
                            else
                            { m_pathAndTime.Add(name, 1); }
                        }
                    }
                }
            }

            foreach (var item in m_pathAndTime)
            {
                if (item.Value >= 2)
                {
                    string name = "Assets/" + item.Key;
                    AssetImporter resAsset = AssetImporter.GetAtPath(name);
                    if (resAsset != null )
                    {
                        name = name.Replace("Assets/", "");
                        name = name.Substring(0, name.LastIndexOf('.'));
                        resAsset.assetBundleName = name;
                    }
                }
                else
                {

                }
            }

            for (int i = 0; i < prefableArr.Length; i++)
            {
                string tmpPath = AssetDatabase.GetAssetPath(prefableArr[i]);
                string[] ObjPath = AssetDatabase.GetDependencies(tmpPath);
                for (int j = 0; j < ObjPath.Length; j++)
                {
                    if (ObjPath[j].StartsWith("Assets/Resources/"))
                    {
                        AssetImporter resAsset = AssetImporter.GetAtPath(ObjPath[j]);
                        if (resAsset != null)
                        {
                            string name = ObjPath[j].Substring(0, ObjPath[j].LastIndexOf('.'));
                            name = name.Replace("Assets/Resources/", "");
                            resAsset.assetBundleName = name;
                        }
                    }
                }
            }
            BuildPipeline.BuildAssetBundles(Application.dataPath + "/StreamingAssets", BuildAssetBundleOptions.ChunkBasedCompression,BuildTarget.StandaloneWindows);
            AssetDatabase.Refresh();
        }
    }

        2.清除之前的所有AssetBundle Lable内容

    [MenuItem("tool/clean all res")]
    static void CleanAbInfo()
    {
        string[] allLabName = AssetDatabase.GetAllAssetBundleNames();
        for (int i = 0; i < allLabName.Length; i++)
        {
            AssetDatabase.RemoveAssetBundleName(allLabName[i], true);
        }
        Resources.UnloadUnusedAssets();
    }

        3.调试加载工具(可以直接挪入到资源管理器中,每个项目的资源管理都不太一样,我就不单独放我的资源管理类了)

    [MenuItem("tool/test load ab")]
    static void LoadAb()
    {
        //
        AssetBundle assetBundleManifest = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/AssetBundles");
        if (null != assetBundleManifest)
        {
            AssetBundleManifest manifest = assetBundleManifest.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
            if (manifest != null)
            {
                //AssetBundle testBundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/effect/link12");
                //if (null != testBundle)
                {
                    string[] allDepends = manifest.GetAllDependencies("effect/link12");

                    AssetBundle[] dependAsset = new AssetBundle[allDepends.Length];
                    for (int i = 0; i < allDepends.Length; i++)
                    {
                        string pathName = Application.dataPath + "/AssetBundles/" + allDepends[i];
                        dependAsset[i] = AssetBundle.LoadFromFile(pathName);
                        if(dependAsset[i] == null)
                        { Debug.LogError("引用资源没有找到"+ pathName); }
                        else
                        { /*Object[] has = dependAsset[i].LoadAllAssets();*/ }
                    }
                    AssetBundle testBundle = AssetBundle.LoadFromFile(Application.dataPath + "/AssetBundles/effect/link12");
                    if (null != testBundle)
                    {
                        GameObject needInfo = testBundle.LoadAsset("link12") as GameObject;
                        if (needInfo != null)
                        {
                            GameObject ui = (GameObject)Instantiate(needInfo);
                        }
                    }

                    for (int i = 0; i < allDepends.Length; i++)
                    {
                        if(dependAsset[i] != null)
                        {
                            dependAsset[i].Unload(false);
                        }
                    }
                    testBundle.Unload(false);
                }
                assetBundleManifest.Unload(false);
            }
        }
        Resources.UnloadUnusedAssets();
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值