Unity5.x AssetBundle打包和加载深入分析

来源:互联网 发布:sso算法 编辑:程序博客网 时间:2024/05/29 19:57

Unity5.x AssetBundle打包和加载深入分析

1.打包

unity 可以通过为资源设置assetBundleName的方式打包资源首先我们需要批量为资源设置assetBundleName
上代码:

public static void ReName()    {        Object[] objs = Selection.objects;        for (int i = 0; i < objs.Length; i++)        {            string path = AssetDatabase.GetAssetPath(objs[i]);            FileInfo dir = new FileInfo(path);            string parent = dir.Directory.Name;            AssetImporter.GetAtPath(path).assetBundleName = parent + "/" + objs[i].name;            if (i % 10 == 0)            {                bool isCancel = EditorUtility.DisplayCancelableProgressBar("修改中", path, (float)i / objs.Length);                if (isCancel)                {                    EditorUtility.ClearProgressBar();                    break;                }            }        }        EditorUtility.ClearProgressBar();    }

其中
AssetImporter.GetAtPath(path).assetBundleName="name"
就是为资源设置assetBundleName
可以以路径的形式命名,打包时会自动打包到相应的路径下,比如:
AssetImporter.GetAtPath(path).assetBundleName="aaa/bb/name"

资源命名好了之后,下面就开始打包了
打包代码只需要一句
BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.Android);
便可将资源打包到相应目录和对应的平台。

下面是我的测试
这里写图片描述
这里我将两个sprite打包
这里写图片描述
可以看到这里已经将AssetBundle 打包到了AssetBundles的Sprite文件夹下。到这里打包的过程就算结束了

加载

打包完成后剩下的自然就是加载
我们先将刚才打包的两个Sprite加载出来:

        Object[] sprites = bundle2.LoadAssetWithSubAssets(bundle.GetAllAssetNames()[0], typeof(GameObject));        GameObject sprite = GameObject.Instantiate(sprites[0]) as GameObject;        AssetBundle bundle1 = AssetBundle.LoadFromFile("Assets/AssetBundles/sprites/sprite-00010");        Object[] sprites1 = bundle2.LoadAssetWithSubAssets(bundle1.GetAllAssetNames()[0], typeof(GameObject));        GameObject sprite1 = GameObject.Instantiate(sprites1[0]) as GameObject;

通过这段代码将资源加载到内存中
这里写图片描述
运行后同过Pfofiler查看,发现内存中存在两份Sprite-00010的贴图
这里写图片描述
这是因为两个Sprite都引用了同一份贴图
导致贴图打包重复
解决这个问题的思路有两个
1.将有同样贴图的资源打包到一个AssetBundle里
2.为被引用的贴图设置AssetBundleName,这样打包时会将贴图也打包成AssetBundle并自动处理引用
这里我们测试第二种
将贴图打包后我们查看之前Sprite的AssetBundle的信息发现Unity已经自动处理了引用关系:
这里写图片描述
Dependencies就是引用的AssetBundle
所以我们要将其引用的资源也加载进来
完整代码如下:

AssetBundle bundle0 = AssetBundle.LoadFromFile("Assets/AssetBundles/textures/sprite-00010");        AssetBundle bundle = AssetBundle.LoadFromFile("Assets/AssetBundles/sprites/sprite-00010");        Object[] sprites = bundle.LoadAssetWithSubAssets(bundle.GetAllAssetNames()[0], typeof(GameObject));        GameObject sprite = GameObject.Instantiate(sprites[0]) as GameObject;        AssetBundle bundle1 = AssetBundle.LoadFromFile("Assets/AssetBundles/sprites/sprite-00011");        Object[] sprites1 = bundle1.LoadAssetWithSubAssets(bundle1.GetAllAssetNames()[0], typeof(GameObject));        GameObject sprite1 = GameObject.Instantiate(sprites1[0]) as GameObject;        bundle0.Unload(false);        bundle1.Unload(false);        bundle.Unload(false);

再次测试可以看到内存中Sprite-00010的贴图只剩一份了
这里写图片描述
但是加载时难道所有的引用都要手动一个个加载吗
这里写图片描述
这里打包后都会有一个AssetBundles
其中manifest文件中存储了所有AssetBundle的依赖信息
同过下面代码就能获取指定资源的所有依赖资源了

AssetBundle ab = AssetBundle.LoadFromFile("Assets/AssetBundles/AssetBundles");        AssetBundleManifest abm = ab.LoadAsset("AssetBundleManifest") as AssetBundleManifest;        string[] ss = abm.GetAllDependencies("sprites/sprite-00010");

然后就可以遍历加载了。很简单吧

0 2
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 低保户没低保证怎么办 鸿运当头花干了怎么办 鸿运当头花谢了怎么办 鸿运当头花不红怎么办 众筹项目失败了怎么办 孕妇头发白了怎么办呢 猕猴桃坏了吃了怎么办 猕猴桃买的太硬怎么办 金艳猕猴桃很硬怎么办 猕猴桃又硬又酸怎么办 2岁宝宝生长缓慢怎么办 婴儿体重长得慢怎么办 人吃了乌药中毒怎么办 水中的氧气过少怎么办 怀孕9个月血糖高怎么办 怀孕的人血糖高怎么办 来月经很痛该怎么办 月经来了好痛怎么办 花呗额度用完了怎么办 老人长期卧床长了褥疮怎么办 5岁宝宝嗓子哑了怎么办 2岁宝宝喉咙嘶哑怎么办 1岁宝宝嗓子哑了怎么办 3个月婴儿嗓子哑怎么办 小孩一感冒就喘怎么办 狗打双黄连过敏怎么办 过敏怎么办怎么好的快 铁木砧板变形了怎么办 水泥地面起沙严重怎么办 横厅沙发不靠墙怎么办 吃多了胃疼怎么办 龙血树叶子干枯怎么办 龙血树叶尖发黄怎么办 茶花叶子掉光了怎么办 鸡虱子爬人身上怎么办 鸡的身上有虱子怎么办 鸡跳蚤在人身上怎么办 猫虱子到人身上怎么办 大人头上长虱子怎么办 头发上有剪发虫怎么办 头发长白色的虫怎么办