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/MFu6k

猜你喜欢

转载自blog.csdn.net/m0_62921885/article/details/136445455