Unity5.0 AssetBundle 学习心得

    首先,发下参考链接,阿赵的博客,写得很好:

    阿赵文中写过:
    “先来说说最多人关心的问题,Unity自己处理依赖关系。
    实际上来说,所有需要打包成AssetBundle的资源,你是要先赋予它一个assetBundleName的,在它有了assetBundleName之后,实际上它的信息已经存在于AssetDataBase里面了。所以在打包的时候,只需要调用BuildPipeline.BuildAssetBundles方法,它会把记录了的在AssetDataBase里面的所有资源先计算出依赖关系,再拆分打包。这个步骤是一点问题都没有的。要注意的是,你所有依赖的资源都必须赋予assetBundleName,不然,依赖就不会被拆分。”

    我很好奇,使用Unity5,这样打包出来的AssetBundle究竟是什么样。于是参照他的方式,做了下实验。
    仍然是4张贴图,名字分别是T1,T2,T3,T4。2个材质球,M1,使用贴图T1,T2,T3。材质球M2,使用贴图T4。2个Cube物体,obj1和obj2,分别使用材质M1和M2.将obj1和obj2做成prefab。
    打包的代码很简单:
using UnityEngine;
using UnityEditor;

public class BuildAssetBundle : MonoBehaviour {

	// Use this for initialization
	void Start () {
        
	}
	
	// Update is called once per frame
	void Update () {
	
	}

    [MenuItem("AssetBundle/BuildAssetBundle")]
    public static void CreateAssetBundle()
    {
        BuildPipeline.BuildAssetBundles("Assets/Output", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows);
    }
}


    1.只打包prefab
点击obj1,new一个AssetBundle name为“obj1”,同样为obj2 new 一个AssetBundle name为“obj2”,分别设置好。使用上面代码生成的菜单,导出AssetBundle。这样打包一共3个AssetBundle文件,分别是obj1,obj2,还有一个跟导出路径同名的output。其余的manifest文件是本地使用,暂时不关注。

    使用如下加载代码测试:
using UnityEngine;
using System.Collections;

public class ImportAssetBundle : MonoBehaviour {

	// Use this for initialization
	void Start () {
        AssetBundle ab1 = AssetBundle.LoadFromFile("Assets/AssetBundle/obj1");
        if(ab1 != null)
        {
            Debug.Log("ab1 create success!");

            Instantiate(ab1.LoadAsset("oBj1"));
            //Object M1 = ab1.LoadAsset("M1");
            //Debug.Log(M1.name);

            string[] names = ab1.GetAllAssetNames();
            foreach (var elem in names)
                Debug.Log("Asset name is " + elem);

            Object[] objs = ab1.LoadAllAssets();
            foreach (var elem in objs)
                Debug.Log("Obj is " + elem.name);

            Object[] objsWithSub = ab1.LoadAssetWithSubAssets("Obj1");
            foreach (var elem in objsWithSub)
                Debug.Log("Obj with sub assets is " + elem.name);
        }

        AssetBundle ab1Manifest = AssetBundle.LoadFromFile("Assets/AssetBundle/Output");
        if (ab1Manifest != null)
        {
            Debug.Log("ab1Manifest create success!");
            string[] names = ab1Manifest.GetAllAssetNames();
            foreach (var elem in names)
                Debug.Log("asset name is " + elem);

            AssetBundleManifest manifest = ab1Manifest.LoadAsset("AssetBundleManifest") as AssetBundleManifest;
            if(manifest != null)
            {
                Debug.Log("load manifest success");

                string[] AllAB = manifest.GetAllAssetBundles();
                foreach (var elem in AllAB)
                    Debug.Log("AssetBundle is " + elem);

                string[] AllDependences = manifest.GetAllDependencies("obj1");
                foreach (var elem in AllDependences)
                    Debug.Log("Dependences is " + elem);
            }
        }
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

     大家自行运行结果记忆会更深刻。
     分析结果发现, ab1.GetAllAssetNames(),ab1.LoadAllAssets() 能取出来的都只有obj1,而我实例化的obj1立方体可是带有材质和贴图的。放开注释的代码
       //Object M1 = ab1.LoadAsset("M1");
       //Debug.Log(M1.name);

     运行会报错,说是空引用。明明有贴图,材质,可我们就是没法从AssetBundle取出来,只可能是unity自己将我们没有显式设置AssetBundle的资源密封起来了,不让我们去获取。
     之后的代码
   string[] names = ab1Manifest.GetAllAssetNames();
      在实验中得到的只有一个文件,就是assetbundlemanifest,不区分大小写。这个文件包含了所有的依赖关系。
      再看obj1的依赖项
   string[] AllDependences = manifest.GetAllDependencies("obj1");
      结果是空的,没有任何依赖项。可是obj1明明依赖了材质M1,还有贴图啊。
      猜测,是因为M1等资源没有打包的原因,我们验证一下。


    2.将材质,贴图与prefab共同打包到一个AssetBundle下
    将M1,T1,T2,T3的AssetBundle设置成obj1,再次打包,最后生成的文件个数没有变化。然而我们运行代码会发现结果出现了部分变化,首先就是M1能够load出来了,验证了只有显示设置AssetBundle name的资源才可以被我们load使用。
    最后的依赖资源,manifest.GetAllDependencies("obj1")获取的还是空,看看GetAllDependencies函数定义,获取的是依赖的AssetBundle的名字。obj1依赖的所有东西都在自身所在的AssetBundle里,自然获取不到值。再一次反省,看SDK的注释含义。。。


     3.将材质,贴图,prefab分开打包
    将M1的AssetBundle设置为M1,重新打包。生成的文件中多了M1的AssetBundle文件。
    继续使用加载代码,前面大部分相同,当然这次你不能从obj1的AssetBunble中去load试图获取 M1了。最关键的部分在最后,这次我们可以使用GetAllDependencies获取到obj1的依赖文件M1了。


   结语
    只打包prefab,省事,但可能造成资源的重复打包,无法复用。如果是唯一性的东西,只有某个物体使用,可以偷懒这么做。但如果想复用东西,老老实实多拆点小的包出来。当然,灵活性最高的就是用4.0那种自己控制的方式。具体的做法根据需求来取舍吧。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值