AssetBundle单个包的加载

114 阅读1分钟

单个包的加载,需要记录AB包中资源的标签和预制体名; 初始化依赖; 加载AB包; 加载资源; 实例化游戏物体; 释放资源。

主类

public class Main : MonoBehaviour
{
    [Header("标签名:")]
    public string assetBundle;
    [Header("预制体名:")]
    public string prefabName;
    void Awake()
    {
        //初始化
        AssetBundleLoadMgr.Instance.Init();
    }

    void LoadAsset()
    {
        //加载预设
        GameObject prefab = AssetBundleLoadMgr.Instance.LoadAsset<GameObject>(assetBundle, prefabName);
        //实例化预设
        Instantiate(prefab);
        AssetBundleLoadMgr.Instance.RealeaseAssetBundle(assetBundle);
    }
    void OnGUI()
    {
        if (GUI.Button(new Rect(100, 100, 100, 50), "LoadAsset"))
        {
            LoadAsset();
        }

    }
}

单例类

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

    ///<summary>
    ///保存各个AssetBundle的依赖信息
    /// </summary>
    private static AssetBundleManifest m_mainfest;

    /// <summary>
    /// 单例
    /// </summary>
    private static AssetBundleLoadMgr instance;
    public static AssetBundleLoadMgr Instance 
    {
        get 
        { 
            if(null==instance) instance = new AssetBundleLoadMgr();
            return instance;
        }
    }


    ///<summary>
    ///初始化,加载AssetBundleManifest,方便后续查找依赖
    /// </summary>
    public static void Init()
    {
        string streamingAssetsAbPath = Path.Combine(Application.streamingAssetsPath, "StandaloneWindows");
        AssetBundle streamingAssetsAb=AssetBundle.LoadFromFile(streamingAssetsAbPath);
        m_mainfest = streamingAssetsAb.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    }

    /// <summary>
    /// 加载AssetBundle
    /// </summary>
    /// <param name="name">AssetBundle名称</param>
    /// <returns></returns>
    public AssetBundle LoadAssetBundle(string abName)
    {
        AssetBundle ab = null;
        if (!m_abDic.ContainsKey(abName))
        {
            string abResPath = Path.Combine(Application.streamingAssetsPath, abName);
            ab = AssetBundle.LoadFromFile(abResPath);
            m_abDic[abName] = ab;
        }
        else
        { 
            ab = m_abDic[abName];
        }
        return ab;     
    }

    ///<summary>
    ///从AssetBundle加载资源
    /// </summary>
    public T LoadAsset<T>(string abName,string assetName) where T : Object 
    {
        AssetBundle ab = LoadAssetBundle(abName);
        T t=ab.LoadAsset<T>(assetName);
        return t;
    }

    ///<summary>
    ///释放AssetBundle包的资源
    /// </summary>

    public void RealeaseAssetBundle(string abName)
    {
        foreach (AssetBundle bundle in AssetBundle.GetAllLoadedAssetBundles())
        {
            if (bundle.name == abName)
            {
                 bundle.Unload(false);
            }
        }
    }
}

资源复用

实际项目中会有多个预制体有相同的部分,如果将相同部分依次压缩,会造成资源的浪费。为了避免资源的浪费,可以将共同依赖的部分单独作为一个AssetBundle进行压缩,其它不同的部分再各自压缩。这样,不同的部分和共同的部分就形成了依赖关系。在做AB包加载的时候,就需要先加载依赖,再加载不同的部分,不然就会造成资源的丢失。