第51天-AssetBundle(AB包)

笔记:

一.直接导入Project文件下

二.打开window工具栏下的AssetBundle Browser,如果有则导入成功

三,创建AB包

1.创建资源,选择New名字,名字不区分大小写

2.打开window工具栏下的AssetBundle Browser

3.选择要构建的平台,建立AB包文件

4.如果没有报错,则表示创建成功,会在Assets同级目录下生成AssetBundles文件夹,打开该文件夹下一级目录的名字和Output Path最后一级名字相同

 

5.打开后里面有4个文件

6.写代码载入

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LessonAB : MonoBehaviour
{

    // Use this for initialization
    void Start () {
        //1.加载AB包
        AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/StandaloneWindows/Prefabs");                
        //AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath  + "/Prefabs");  //或者streamingAssetsPath路径下的

        //2.从ab保重加载资源
        GameObject cubePrefab = ab.LoadAsset<GameObject>("Cube");
        //3.克隆显示预制体
        Instantiate(cubePrefab);
    }
    
    // Update is called once per frame
    void Update () {
        
    }
}

AB包管理器:ABManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// AB包的管理器, 单例类, 需要继承MonoBehaviour,异步加载时需要使用协同程序
/// </summary>
public class ABManager : AutoMonoSingle<ABManager>
{

    //解决不重复加载的问题, 将加载进来的AB包存储到一个字典中
    //键: ab包的名字,  值: ab包
    private Dictionary<string, AssetBundle> loaded
        = new Dictionary<string, AssetBundle>();

    //加载AB包的路径
    private string path;

    public string Path
    {
        get {
            if (path == null || path == "")
            {
                //根据平台的不同,使用不同的路径
#if UNITY_EDITOR || UNITY_STRANDALONE_WIN
                path = Application.streamingAssetsPath + "/";
#else
                path = Application.persistentDataPath + "/";
#endif
            }
            return path;
        }
    }

    //解决加载AB包的同时,加载依赖, 依赖是从主包来的

    //平台不同,主包的名字不同
    public string MainABName
    {
        get {
#if UNITY_STANDALONE_WIN
            return "StandaloneWindows";
#elif UNITY_ANDROID
            return "Android";
#elif UNITY_IOS
            return "iOS";
#else
            return "Main";
#endif
        }
    }

    /// <summary>
    /// 主包单独存储, 经常使用
    /// </summary>
    private AssetBundle main;
    /// <summary>
    /// 从中获取每个ab包的依赖, 经常使用
    /// </summary>
    private AssetBundleManifest manifest;


    /// <summary>
    /// 通过AB包的名字加载AB包
    /// </summary>
    /// <param name="abName">AB包的名字</param>
    /// <returns></returns>
    public AssetBundle Load(string abName)
    {
        AssetBundle ab = null;
        //判断ab包是否加载过
        if (!loaded.TryGetValue(abName, out ab))
        {
            //未加载过加载
            //加载主包与Manifest
            //判断主包是否加载过
            if (main == null)
            {
                main = AssetBundle.LoadFromFile(Path + MainABName);
            }
            if (manifest == null)
            {
                manifest = main.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
            }

            //通过Manifest获取AB包的依赖
            string[] deps = manifest.GetAllDependencies(abName);

            //加载AB包前, 先加载AB包对应的依赖的AB包
            foreach (string depName in deps)
            {
                //不能递归加载依赖项, 如果两个AB包相互依赖,那么最终递归就没有跳出条件
                //Load(depName);  两个包互相依赖的情况下,直接死递归

                //判断依赖是否加载过
                if (!loaded.ContainsKey(depName))
                {
                    AssetBundle depAB = AssetBundle.LoadFromFile(Path + depName);
                    //将依赖的AB包存储到字典中
                    loaded.Add(depName, depAB);
                }
            }

            //再加载当前要加载的AB包
            ab = AssetBundle.LoadFromFile(Path + abName);
            //添加到字典中
            loaded.Add(abName, ab);
        }
        return ab;
    }

    /// <summary>
    /// 卸载指定名字的AB包
    /// </summary>
    /// <param name="abName">AB包的名字</param>
    /// <param name="unloadAllLoadedObjects">是否同时卸载从AB包中加载的资源</param>
    public void Unload(string abName, bool unloadAllLoadedObjects = false)
    {
        AssetBundle ab = null;
        //判断是否加载过
        if (loaded.TryGetValue(abName, out ab))
        {
            //只有获取到AB包的情况下才卸载
            ab.Unload(unloadAllLoadedObjects);
            //将其中字典中移除
            loaded.Remove(abName);
        }
    }

    /// <summary>
    /// 卸载所有的AB包
    /// </summary>
    /// <param name="unloadAllLoadedObjects"></param>
    public void UnloadAll(bool unloadAllLoadedObjects = false)
    {        
        //遍历加载过的所有的AB包,依次卸载
        foreach (var ab in loaded.Values)
        {
            ab.Unload(unloadAllLoadedObjects);
        }
        //清空字典
        loaded.Clear();
    }


    /// <summary>
    /// 非泛型的,从指定的AB包中加载指定的资源 
    /// </summary>
    /// <param name="abName">AB包的名字</param>
    /// <param name="assetName">资源的名字</param>
    /// <returns></returns>
    public Object LoadAsset(string abName, string assetName)
    {
        //加载AB包
        AssetBundle ab = Load(abName);
        //再从AB包中加载资源
        if (ab != null)
        {
            return ab.LoadAsset(assetName);
        }
        return null;
    }

    /// <summary>
    /// 泛型,从指定的AB包中加载指定的资源
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="abName"></param>
    /// <param name="assetName"></param>
    /// <returns></returns>
    public T LoadAsset<T>(string abName, string assetName) where T : Object
    {
        //加载AB包
        AssetBundle ab = Load(abName);
        //再从AB包中加载资源
        if (ab != null)
        {
            return ab.LoadAsset<T>(assetName);
        }
        return default(T);
    }

}
原文地址:https://www.cnblogs.com/yifengs/p/14536423.html