Unity-AssetBundle Browser 打包和加载

一、AssetBundle Browser资源的导入

进入unity手册中,搜素 Unity Asset Bundle Browser 工具,选择你使用的版本号,根据显示出的操作进行资源导入即可。

注:有的版本可能没有资源链接,可以百度一下有很多。

二、AssetBundle Browser 打包

1、制作预制体(省略) 
2、选择一个预制体,在Inspector窗口下方,设置预制体的ab包名(包名只能为小写字母)

3、包体设置
在Window-AssetBundle Browser出现操作页面。

这是刚才把两个预制体设置为ab包,现在两个包后面显示黄色感叹号,这是因为两个预制体里有相同的材质和预制体。 如果直接打包这两个包体存在相同的资源,包体会大,还会重复加载资源。我们这里把相同的资源存放到另外的包体中当作依赖来加载。
4、处理依赖资源
在左侧区域右键-Add new bundle命名为rackmat,把其中一个包体里带有黄色感叹号的资源拖到rackmat里。

5、输出打包
在Build页面,设置打包的配置,选择要打包的平台,勾选Clear Folders重新打包时会清除之前打包的文件。 点击Build后,资源会打包的输出路径的位置,同时也会复制出一个StreamingAssets文件夹,里面也会有一份打包文件。

               

                        输出的文件                                                              复制出的文件 

三、AssetBundle Browser 加载

    
    /// <summary>
    /// 缓存加载的AssetBundle,防止多次加载
    /// </summary>
    private Dictionary<string, AssetBundle> m_abDic = new Dictionary<string, AssetBundle>();

    /// <summary>
    /// 它保存了各个AssetBundle的依赖信息
    /// </summary>
    private AssetBundleManifest abMainfest = null;

     /// <summary>
    /// 主包
    /// </summary>
    private AssetBundle abMain = null;

    /// <summary>
    /// 打包成不同平台对应的路径
    /// </summary>
    private string PathURL
    {
      get
        {

        #if UNITY_EDITOR || UNITY_STANDALONE
                return Application.dataPath + "/StreamingAssets/";
        #elif UNITY_IPHONE
                return Application.dataPath + "/Raw/";
        #elif UNITY_ANDROID
                return Application.dataPath + "!/assets/";
        #endif
        }
    }
     
    /// <summary>
    /// 打包成不同平台对应的主包名称
    /// </summary>
    private string MainABName
    {
        get
        {
        #if UNITY_EDITOR || UNITY_STANDALONE
                return "StandaloneWindows";
        #elif UNITY_IPHONE
                return "IOS";
        #elif UNITY_ANDROID
                return "Android";
        #endif
        }
    }
1、先加载主包,就是包含所有依赖信息的包。
2、通过主包文件,就可以看到当前一共有三个ab包分别是bigrack、smallrack和rackmat,和上文创建的ab包一致。在上文中,把bigrack和samllrack的材质和其他共同资源放到了rackmat包里,所以rackmat是bigrack和smallrack的依赖包。

                                                                        依赖包信息 

3、当加载ab包时,先通过主包查看它是否有依赖,如果有就加载它加入到字典中,方便下次再次加载,然后再加载ab包。
    
    // 初始化,加载AssetBundleManifest,方便后面查找依赖

    public void Init(string abName)
    {
        //加载主包
        if (abMain == null)
        {
            abMain = AssetBundle.LoadFromFile(PathURL + MainABName);
            //获取主包下的AssetBundleManifest资源文件(存有依赖信息)
            abMainfest = abMain.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
        }

        //加载依赖
        AssetBundle ab = null;
        string[] dependences = abMainfest.GetAllDependencies(abName);
        if (dependences.Length > 0)
        {
            for (int i = 0; i < dependences.Length; i++)
            {
                if (!m_abDic.ContainsKey(dependences[i]))
                {
                    ab = AssetBundle.LoadFromFile(PathURL + dependences[i]);
                    m_abDic.Add(dependences[i], ab);
                }
            }
        }
        //加载ab包
        if (!m_abDic.ContainsKey(abName))
        {
            ab = AssetBundle.LoadFromFile(PathURL + abName);
            m_abDic[abName] = ab;
        }
    }

4、同步加载 

    //====================同步加载方式=================

    /// <summary>
    /// 指定类型同步加载
    /// </summary>
    /// <param name="abName">ab包名</param>
    /// <param name="resName">包里资源的具体名(预制体)</param>
    /// <returns></returns>
    public Object LoadAssetBundle(string abName, string resName)
    {
        Init(abName);
        Object obj = m_abDic[abName].LoadAsset(resName);
        return obj;
    }

    //泛型
    public T LoadAssetBundle<T>(string abName, string resName) where T : Object
    {
        Init(abName);
        T obj = m_abDic[abName].LoadAsset<T>(resName);
        return obj;
    }

5、异步加载 

    //====================异步加载方式=================

    /// <summary>
    /// 指定类型异步加载
    /// </summary>
    /// <param name="abName">ab包名</param>
    /// <param name="resName">包里资源的具体名(预制体)</param>
    /// <param name="callBack">回调函数</param>
     public void LoadAssetAsync(string abName, string resName, UnityAction<Object> callBack)
    {
        StartCoroutine(ReallyLoadResAsync(abName, resName, callBack));
    }
    private IEnumerator ReallyLoadResAsync(string abName, string resName, UnityAction<Object> callBack)
    {
        Init(abName);
        AssetBundleRequest abRuqest = m_abDic[abName].LoadAssetAsync(resName);
        yield return abRuqest;
        callBack(abRuqest.asset);
    }


    //泛型
    public void LoadAssetAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object
    {
        StartCoroutine(ReallyLoadResAsync<T>(abName, resName, callBack));
    }
    private IEnumerator ReallyLoadResAsync<T>(string abName, string resName, UnityAction<T> callBack) where T : Object
    {
        Init(abName);
        AssetBundleRequest abRuqest = m_abDic[abName].LoadAssetAsync<T>(resName);
        yield return abRuqest;
        callBack(abRuqest.asset as T);
    }

6、卸载ab包 
    //====================AB包的两种卸载方式=================

    //单个包卸载
    public void UnLoad(string abName)
    {
        if (m_abDic.ContainsKey(abName))
        {
            m_abDic[abName].Unload(false);
            //注意缓存需一并移除
            m_abDic.Remove(abName);
        }
    }

    //所有包卸载
    public void UnLoadAll()
    {
        AssetBundle.UnloadAllAssetBundles(true);
        //注意清空缓存
        m_abDic.Clear();
        abMain = null;
        abMainfest = null;
    }

7、测试
  
    public Transform[] bigRackPos;
    public Transform[] smallRackPos;

    private void Start()
    {
        LoadRack();
        LoadRackAsync();
    }

    //同步加载 
    public void LoadRack()
    {
        GameObject prefab = AssetBundleLoaderMgr.Instance.LoadAssetBundle<GameObject>("smallrack", "SmallRack");
        for (int i = 0; i < smallRackPos.Length; i++)
        {
            //实例化预设
            Instantiate(prefab, smallRackPos[i].position, Quaternion.Euler(0, 90, 0));
        }
    }
    //异步加载
    public void LoadRackAsync()
    {
        AssetBundleLoaderMgr.Instance.LoadAssetRequest<GameObject>("bigrack", "BigRack", (obj) =>
         {
             for (int i = 0; i < bigRackPos.Length; i++)
             {
                 //实例化预设
                 Instantiate(obj, bigRackPos[i].position, Quaternion.identity);
             }
         });
    }

8、成功加载出ab包 

注:当前这些方法适合PC、IOS、Android项目加载ab包资源,对于WebGL项目加载ab包资源就不适用了。由于WebGL的特殊性,我会专门写一篇针对web的ab包加载。

 http://t.csdnimg.cn/31Y0Licon-default.png?t=N7T8http://t.csdnimg.cn/31Y0L

  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AssetBundle 引用计数是指在使用 AssetBundle 打包资源的时候,记录每个 AssetBundle 被使用的次数,以便在使用完后及时释放资源,从而避免内存泄漏。在使用 AssetBundle 资源时,会对的 AssetBundle 进行引用计数的增,使用完后再进行引用计数的减少,当引用计数为 0 时,就可以释放该 AssetBundle 的资源。 AssetBundle 的打包一般分为以下几个步骤: 1. 打包资源文件:使用 Unity Editor 自带的 AssetBundle 打包工具,将需要打包的资源文件进行打包,生成 AssetBundle 文件。 2. AssetBundle 文件:在游戏运行时,使用 Unity 提供的 AssetBundle.LoadFromFile 或 AssetBundle.LoadFromMemory 函数来 AssetBundle 文件。 3. 资源文件:使用的 AssetBundle,使用 AssetBundle.LoadAsset 或 AssetBundle.LoadAssetAsync 函数需要使用的资源文件。 4. 使用完成后,释放资源:使用 AssetBundle.Unload(false) 函数来释放 AssetBundle 中的资源,同时进行引用计数的减少。如果不再需要该 AssetBundle 中的任何资源,可以使用 AssetBundle.Unload(true) 函数来彻底释放该 AssetBundle,包括清除 AssetBundle 的缓存。 使用 AssetBundle 打包资源可以有效地减少应用程序的内存占用,提高应用程序的性能。同时,在使用 AssetBundle 的时候,需要注意避免重复同一个 AssetBundle,以及及时释放不再使用的 AssetBundle 资源,避免内存泄漏。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值