Пример #1
0
    /// <summary>
    /// 同步加载资源
    /// </summary>
    private void loadAssetSync()
    {
        //通过资源名(即AB名)定位相关资源
        var assetspath = AssetDatabase.GetAssetPathsFromAssetBundle(AssetBundleName);

        if (assetspath.Length == 0)
        {
            ResourceLogger.logErr(string.Format("找不到资源名 : {0}的资源!", AssetBundleName));
        }
        else
        {
            mResourceInfo = createAssetDatabaseInfo(AssetBundleName, assetspath);
            mResourceInfo.updateLastUsedTime();
        }

        ///AssetDatabase模式下没有依赖资源的概念,
        ///所以一口气回调资源加载任务完成和上层逻辑回调
        LoadState = ResourceLoadState.SelfComplete;
        LoadSelfResourceCompleteNotifier(this);
        LoadSelfResourceCompleteNotifier = null;

        LoadState = ResourceLoadState.AllComplete;
        mResourceInfo.mIsReady = true;
        LoadResourceCompleteCallBack(mResourceInfo);
        LoadResourceCompleteCallBack = null;

        // 资源加载完成后,AssetDatabaseLoader的任务就完成了,回收重用
        AssetDatabaseLoaderFactory.recycle(this);
    }
    /// <summary>
    /// AB加载携程
    /// </summary>
    /// <returns></returns>
    private IEnumerator assetBundleLoadAsync()
    {
        while (true)
        {
            if (ABAsyncQueue.Count > 0)
            {
                CurrentLoadingAssetBundleLoader = ABAsyncQueue.Dequeue();
                //检查是否已经同步加载完成
                //如果异步加载AB时,同步请求来了,打断异步后续逻辑
                //LoadState == ResourceLoadState.None表明同步加载该资源已经完成,无需再异步返回
                if (CurrentLoadingAssetBundleLoader.LoadState == ResourceLoadState.None)
                {
                    //ResourceLogger.logWar("有资源还未开始异步加载就被同步加载打断!");
                }
                else
                {
                    CurrentLoadingAssetBundleLoader.LoadState = ResourceLoadState.Loading;
                    var abname = CurrentLoadingAssetBundleLoader.AssetBundleName;
                    var abpath = AssetBundlePath.GetABLoadFullPath(abname);
                    AssetBundleCreateRequest abrequest = null;
#if UNITY_EDITOR
                    //因为资源不全,很多资源丢失,导致直接报错
                    //这里临时先在Editor模式下判定下文件是否存在,避免AssetBundle.LoadFromFileAsync()直接报错
                    if (System.IO.File.Exists(abpath))
                    {
                        abrequest = AssetBundle.LoadFromFileAsync(abpath);
                    }
                    else
                    {
                        Debug.LogError(string.Format("AB : {0}文件不存在!", CurrentLoadingAssetBundleLoader.AssetBundleName));
                    }
#else
                    abrequest = AssetBundle.LoadFromFileAsync(abpath);
#endif
                    yield return(abrequest);

                    //如果异步加载AB时,同步请求来了,打断异步后续逻辑
                    //LoadState == ResourceLoadState.None表明同步加载该资源已经完成,无需再异步返回
                    if (CurrentLoadingAssetBundleLoader.LoadState == ResourceLoadState.None)
                    {
                        ResourceLogger.log(string.Format("资源 : {0}加载已完成,异步加载被打断!", abname));
                    }
                    else
                    {
                        var assetbundle = abrequest.assetBundle;
                        if (assetbundle == null)
                        {
                            ResourceLogger.logErr(string.Format("Failed to load AssetBundle : {0}!", CurrentLoadingAssetBundleLoader.AssetBundleName));
                        }
                        CurrentLoadingAssetBundleLoader.onSelfABLoadComplete(assetbundle);
                    }
                }
                CurrentLoadingAssetBundleLoader = null;
            }
            else
            {
                yield return(null);
            }
        }
    }
Пример #3
0
    /// <summary>
    /// 同步加载资源
    /// </summary>
    private void loadAssetSync()
    {
        if (string.IsNullOrEmpty(AssetBundlePath))
        {
            ResourceLogger.logErr(string.Format("找不到资源名 : {0}的资源!", AssetBundlePath));
        }
        else
        {
            mResourceInfo = createAssetDatabaseInfo(AssetBundlePath);
            mResourceInfo.updateLastUsedTime();
        }

        ///AssetDatabase模式下没有依赖资源的概念,
        ///所以一口气回调资源加载任务完成和上层逻辑回调
        LoadState = ResourceLoadState.SelfComplete;
        LoadSelfResourceCompleteNotifier(this);
        LoadSelfResourceCompleteNotifier = null;

        LoadState = ResourceLoadState.AllComplete;
        mResourceInfo.mIsReady = true;
        LoadResourceCompleteCallBack(mResourceInfo);
        LoadResourceCompleteCallBack = null;

        // 资源加载完成后,AssetDatabaseLoader的任务就完成了,回收重用
        AssetDatabaseLoaderFactory.recycle(this);
    }
Пример #4
0
 public override T loadAsset <T>(string assetname)
 {
     if (mIsReady)
     {
         if (mLoadedAssetMap.ContainsKey(assetname))
         {
             return(mLoadedAssetMap[assetname] as T);
         }
         else
         {
             var assetpath = $"{AssetBundlePath}/{assetname}";
             T   asset     = AssetDatabase.LoadAssetAtPath <T>(assetpath);
             if (asset != null)
             {
                 mLoadedAssetMap.Add(assetname, asset);
                 return(asset);
             }
             else
             {
                 ResourceLogger.logErr(string.Format("找不到符合类型 : {0},资源名: {1},Asset : {2}资源!", typeof(T).GetType(), AssetBundlePath, assetname));
                 return(null);
             }
         }
     }
     else
     {
         ResourceLogger.logErr(string.Format("异常状态,AB资源:{0}未就绪就请求Asset资源:{1}", AssetBundlePath, assetname));
         return(null);
     }
 }
Пример #5
0
 /// <summary>
 /// 加载所有Asset(比如Shader预加载)
 /// Note:
 /// 加载图集使用loadAllAsset<Sprite>()或者loadAsset<Sprite>
 /// </summary>
 /// <param name="assetname"></param>
 /// <returns></returns>
 public override void loadAllAsset <T>()
 {
     if (mIsReady)
     {
         if (!mIsAllAssetLoaded)
         {
             foreach (var assetpath in AssetsPath)
             {
                 var allassets = AssetDatabase.LoadAllAssetsAtPath(assetpath);
                 foreach (var asset in allassets)
                 {
                     var assetname = asset.name;
                     if (!mLoadedAssetMap.ContainsKey(assetname))
                     {
                         mLoadedAssetMap.Add(assetname, asset);
                     }
                     else
                     {
                         ResourceLogger.logErr(string.Format("资源名 : {0}里有同名资源!Asset资源 : {1}添加失败!请优化取名,避免重名Asset!", AssetBundleName, assetname));
                     }
                 }
             }
             mIsAllAssetLoaded = true;
         }
     }
 }
Пример #6
0
 /// <summary>
 /// 开始资源加载任务
 /// </summary>
 public void startLoad()
 {
     if (LoadState == ResourceLoadState.None)
     {
         LoadState = ResourceLoadState.Waiting;
         loadAsset();
     }
     else if (LoadState == ResourceLoadState.Waiting)
     {
         ResourceLogger.logErr(string.Format("AB : {0}处于等待加载中状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName));
     }
     else if (LoadState == ResourceLoadState.Loading)
     {
         ResourceLogger.logErr(string.Format("AB : {0}处于加载中状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName));
     }
     else if (LoadState == ResourceLoadState.SelfComplete)
     {
         ResourceLogger.logErr(string.Format("AB : {0}已经处于自身加载完成状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName));
     }
     else if (LoadState == ResourceLoadState.AllComplete)
     {
         ResourceLogger.logErr(string.Format("AB : {0}已经处于自身以及依赖AB加载完成状态,不应该再被调用startLoad,请检查资源加载是否异常!", AssetBundleName));
     }
     else if (LoadState == ResourceLoadState.Error)
     {
         ResourceLogger.logErr(string.Format("AB:{0}处于Error状态,无法加载!", AssetBundleName));
     }
 }
Пример #7
0
    /// <summary>
    /// 强制卸载指定资源(不管AB加载后属于哪一种类型,强制卸载)
    /// </summary>
    /// <param name="abname"></param>
    public void forceUnloadSpecificResource(string abname)
    {
        ResourceLoadType     resourceloadtype = ResourceLoadType.NormalLoad;
        AbstractResourceInfo arinfo           = null;

        foreach (var loadedabinfomap in mAllLoadedResourceInfoMap)
        {
            if (arinfo != null)
            {
                break;
            }

            foreach (var loadedabinfo in loadedabinfomap.Value)
            {
                if (loadedabinfo.Key.Equals(abname))
                {
                    arinfo           = loadedabinfo.Value;
                    resourceloadtype = loadedabinfomap.Key;
                    break;
                }
            }
        }

        if (arinfo != null)
        {
            mAllLoadedResourceInfoMap[resourceloadtype].Remove(arinfo.AssetBundleName);
            arinfo.dispose();
            ResourceLogger.log(string.Format("AB资源 : {0}已强制卸载!", abname));
        }
        else
        {
            ResourceLogger.logErr(string.Format("AB资源 : {0}未被加载,无法强制卸载!", abname));
        }
    }
Пример #8
0
 /// <summary>
 /// 卸载指定类型不再使用的资源(Note:不支持卸载常驻资源类型)
 /// </summary>
 /// <param name="resourceloadtype">资源加载类型</param>
 protected void unloadSpecificLoadTypeUnsedResource(ResourceLoadType resourceloadtype)
 {
     if (resourceloadtype == ResourceLoadType.PermanentLoad)
     {
         ResourceLogger.logErr("不允许卸载常驻AB资源!");
         return;
     }
     doUnloadSpecificLoadTypeUnsedResource(resourceloadtype);
 }
Пример #9
0
 /// <summary>
 /// 添加指定资源到白名单
 /// Note:
 /// 默认白名单里的资源都以ResourceLoadType.Preload方式加载
 /// </summary>
 /// <param name="resname">资源名(既AB名)</param>
 public void addToWhiteList(string resname)
 {
     if (!mResourceWhileListMap.ContainsKey(resname))
     {
         mResourceWhileListMap.Add(resname, resname);
     }
     else
     {
         ResourceLogger.logErr(string.Format("资源 : {0}重复添加白名单!", resname));
     }
 }
 /// <summary>
 /// 异步加载任务入队列
 /// </summary>
 /// <param name="abl"></param>
 public static void enqueue(AssetBundleLoader abl)
 {
     if (abl.LoadMethod == ResourceLoadMethod.Async)
     {
         ABAsyncQueue.Enqueue(abl);
     }
     else
     {
         ResourceLogger.logErr(string.Format("严重错误,同步加载资源 : {0} 不应该添加到异步加载队列里!", abl.AssetBundleName));
     }
 }
 /// <summary>
 /// 启动AB异步加载任务携程
 /// </summary>
 public void startABAsyncLoad()
 {
     if (IsLoadStart == false)
     {
         CoroutineManager.Singleton.StartCoroutine(assetBundleLoadAsync());
         IsLoadStart = true;
     }
     else
     {
         ResourceLogger.logErr("AB异步加载任务携程已经启动!不能重复开启!");
     }
 }
Пример #12
0
 /// <summary>
 /// 获取指定加载类型的已加载资源信息映射Map
 /// </summary>
 /// <param name="loadtype">资源加载类型</param>
 /// <returns></returns>
 public Dictionary <string, AbstractResourceInfo> getSpecificLoadTypeARIMap(ResourceLoadType loadtype)
 {
     if (mAllLoadedResourceInfoMap.ContainsKey(loadtype))
     {
         return(mAllLoadedResourceInfoMap[loadtype]);
     }
     else
     {
         ResourceLogger.logErr(string.Format("找不到资源类型 : {0}的已加载AB信息!", loadtype));
         return(null);
     }
 }
 /// <summary>
 /// 开始资源加载卸载统计
 /// </summary>
 public void startResourceLoadAnalyse()
 {
     if (ResourceLoadAnalyseSwitch)
     {
         ResourceLoadAnalyseStart = true;
         ResourceLoadAnalyseMap.Clear();
         ResourceLogger.log("开启AB加载统计!");
     }
     else
     {
         ResourceLogger.logErr("请先开启AB资源加载分析开关!");
     }
 }
Пример #14
0
 /// <summary>
 /// 更新已加载AB的加载类型
 /// </summary>
 /// <param name="resname">资源名</param>
 /// <param name="oldloadtype">旧的加载类型</param>
 /// <param name="newloadtype">新的家在类型</param>
 protected void updateLoadedResourceInfoLoadType(string resname, ResourceLoadType oldloadtype, ResourceLoadType newloadtype)
 {
     if (mAllLoadedResourceInfoMap[oldloadtype].ContainsKey(resname))
     {
         var abi = mAllLoadedResourceInfoMap[oldloadtype][resname];
         mAllLoadedResourceInfoMap[newloadtype].Add(resname, abi);
         mAllLoadedResourceInfoMap[oldloadtype].Remove(resname);
         ResourceLogger.log(string.Format("已加载的资源 : {0}从资源类型 : {1}更新到资源类型 : {2}!", resname, oldloadtype, newloadtype));
     }
     else
     {
         ResourceLogger.logErr(string.Format("资源类型 : {0}里找不到已加载的资源 : {1},无法更新该资源的加载类型!", oldloadtype, resname));
     }
 }
Пример #15
0
    /// <summary> AB加载完成通知(用于更新AB加载管理) /// </summary>
    /// <param name="abl">AB加载任务信息</param>
    private void onABLoadCompleteNotifier(AssetBundleLoader abl)
    {
        var abname = abl.AssetBundleName;

        if (mABRequestTaskMap.ContainsKey(abname))
        {
            mABRequestTaskMap.Remove(abname);
            mAllLoadedResourceInfoMap[abl.LoadType].Add(abname, abl.ABInfo);
            //AB加载数据统计
            if (ResourceLoadAnalyse.Singleton.ResourceLoadAnalyseSwitch)
            {
                ResourceLoadAnalyse.Singleton.addResourceLoadedTime(abname);
            }
        }
        else
        {
            ResourceLogger.logErr(string.Format("收到不在加载任务请求队列里的AB:{0}加载完成回调!", abname));
        }
    }
    /// <summary>
    /// 为AB添加指定owner的引用
    /// 所有owner都销毁则ab引用计数归零可回收
    /// </summary>
    /// <param name="owner"></param>
    protected void retainOwner(UnityEngine.Object owner)
    {
        if (owner == null)
        {
            ResourceLogger.logErr(string.Format("引用对象不能为空!无法为资源:{0}添加引用!", AssetBundlePath));
            return;
        }

        foreach (var referenceowner in mReferenceOwnerList)
        {
            if (owner.Equals(referenceowner))
            {
                return;
            }
        }

        System.WeakReference wr = new System.WeakReference(owner);
        mReferenceOwnerList.Add(wr);
    }
Пример #17
0
    /// <summary>
    /// 实例化指定Asset(上层获取并绑定Asset实例化GameObject对象接口)
    /// </summary>
    /// <param name="assetname"></param>
    /// <returns></returns>
    public override GameObject instantiateAsset(string assetname)
    {
        var goasset = loadAsset <GameObject>(assetname);

        if (goasset != null)
        {
            var goinstance = GameObject.Instantiate <GameObject>(goasset);
            //不修改实例化后的名字,避免上层逻辑名字对不上
            //goinstance.name = goasset.name;
            // 绑定owner对象,用于判定是否还有有效对象引用AB资源
            retainOwner(goinstance);
            updateLastUsedTime();
            return(goinstance);
        }
        else
        {
            ResourceLogger.logErr(string.Format("AB:{0}里加载GameObject Asset:{1}失败!", AssetBundleName, assetname));
            return(null);
        }
    }
 /// <summary>
 /// 停止资源加载卸载统计并输出
 /// </summary>
 public void endResourceLoadAnalyse()
 {
     if (ResourceLoadAnalyseSwitch)
     {
         if (ResourceLoadAnalyseStart)
         {
             ResourceLoadAnalyseStart = false;
             outputResourceLoadedInfoDetail();
             ResourceLoadAnalyseMap.Clear();
             ResourceLogger.log("结束资源加载统计!");
         }
         else
         {
             ResourceLogger.logErr("请先启动资源加载统计!");
         }
     }
     else
     {
         ResourceLogger.logErr("请先开启资源资源加载分析开关!");
     }
 }
    /// <summary>
    /// 移除指定拥有者绑定(用于解决上层绑定对象一直存在导致资源无法释放的问题)
    /// </summary>
    /// <param name="owner"></param>
    /// <returns></returns>
    public bool releaseOwner(UnityEngine.Object owner)
    {
        if (owner == null)
        {
            ResourceLogger.logErr(string.Format("引用对象不能为空!无法为资源:{0}解除绑定!", AssetBundlePath));
            return(false);
        }

        var ownerindex = mReferenceOwnerList.FindIndex((ow) => ow.Target.Equals(owner));

        if (ownerindex != -1)
        {
            ResourceLogger.log(string.Format("资源:{0}找到指定绑定对象:{1},解除绑定!", AssetBundlePath, owner));
            mReferenceOwnerList.RemoveAt(ownerindex);
            return(true);
        }
        else
        {
            ResourceLogger.log(string.Format("资源:{0}找不到指定绑定对象:{1},解除绑定失败!", AssetBundlePath, owner));
            return(false);
        }
    }
Пример #20
0
    /// <summary>
    /// 资源请求携程
    /// </summary>
    /// <returns></returns>
    private IEnumerator resourcesRequest()
    {
        foreach (var hotupdateres in mTestHotUpdateResourceList)
        {
            var resurl = TestResourceURL + hotupdateres;
            ResourceLogger.log(string.Format("下载资源 : {0}", resurl));
            var webrequest = UnityWebRequest.Get(resurl);
            yield return(webrequest.SendWebRequest());

            if (webrequest.isNetworkError)
            {
                ResourceLogger.logErr(string.Format("{0}资源下载出错!", hotupdateres));
                ResourceLogger.logErr(webrequest.error);
            }
            else
            {
                if (webrequest.isDone)
                {
                    ResourceLogger.log(string.Format("{0}资源下载完成!", hotupdateres));
                    var data = webrequest.downloadHandler.data;
                    //检查包外是否存在同名资源,存在的话需要先删除再存储最新到包外
                    var outterabfullpath = AssetBundlePath.ABHotUpdatePath + hotupdateres;
                    if (AssetBundlePath.IsABExitInOutterPath(hotupdateres))
                    {
                        ResourceLogger.log(string.Format("删除包外资源 : {0}", hotupdateres));
                        File.Delete(outterabfullpath);
                    }
                    using (var fs = File.Create(outterabfullpath))
                    {
                        fs.Write(data, 0, data.Length);
                        fs.Flush();
                        fs.Close();
                        ResourceLogger.log(string.Format("包外资源 : {0}写入完成!", hotupdateres));
                    }
                }
            }
        }
    }
Пример #21
0
 /// <summary>
 /// 加载所有Asset(比如Shader预加载)
 /// Note:
 /// 加载图集使用loadAllAsset<Sprite>()或者loadAsset<Sprite>
 /// </summary>
 /// <param name="assetname"></param>
 /// <returns></returns>
 public override void loadAllAsset <T>()
 {
     if (mIsReady)
     {
         if (!mIsAllAssetLoaded)
         {
             var allassets = Bundle.LoadAllAssets <T>();
             foreach (var asset in allassets)
             {
                 var assetname = asset.name;
                 if (!mLoadedAssetMap.ContainsKey(assetname))
                 {
                     mLoadedAssetMap.Add(assetname, asset);
                 }
                 else
                 {
                     ResourceLogger.logErr(string.Format("资源名 : {0}里有同名资源!Asset资源 : {1}添加失败!", AssetBundlePath, assetname));
                 }
             }
             mIsAllAssetLoaded = true;
         }
     }
 }
Пример #22
0
 /// <summary>
 /// 获取并绑定指定Asste资源(上层获取并绑定特定类型Asset的接口)
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="owner"></param>
 /// <param name="assetname"></param>
 /// <returns></returns>
 public override T getAsset <T>(UnityEngine.Object owner, string assetname)
 {
     if (owner != null)
     {
         var asset = loadAsset <T>(assetname);
         if (asset != null)
         {
             // 绑定owner对象,用于判定是否还有有效对象引用AB资源
             retainOwner(owner);
             updateLastUsedTime();
             return(asset);
         }
         else
         {
             ResourceLogger.logWar(string.Format("AB : {0}里不存在Asset : {1},获取Asset失败!", AssetBundleName, assetname));
             return(null);
         }
     }
     else
     {
         ResourceLogger.logErr(string.Format("不能绑定Asset到空对象上!加载AB:{0} Asset:{1}失败!", AssetBundleName, assetname));
         return(null);
     }
 }
Пример #23
0
 /// <summary>
 /// 加载所有Asset(比如Shader预加载)
 /// Note:
 /// 加载图集使用loadAllAsset<Sprite>()或者loadAsset<Sprite>
 /// </summary>
 /// <param name="assetname"></param>
 /// <returns></returns>
 public override void loadAllAsset <T>()
 {
     if (mIsReady)
     {
         if (!mIsAllAssetLoaded)
         {
             foreach (var assetpath in AssetsPath)
             {
                 var allassets = AssetDatabase.LoadAllAssetsAtPath(assetpath);
                 foreach (var asset in allassets)
                 {
                     var assetname = asset.name;
                     if (!mLoadedAssetMap.ContainsKey(assetname))
                     {
                         mLoadedAssetMap.Add(assetname, asset);
                     }
                     else
                     {
                         if (typeof(T) == typeof(Sprite))
                         {
                             // 暂时用重复的覆盖老(Sprite覆盖Texture2D)的(解决单张图作为Sprite时,Texture2D和Sprite同名的问题)
                             // 问题:
                             // 1. 此方式不会缓存图集的Texture2D(暂时可以通过sprite.Texture的方式访问Texture2D)
                             mLoadedAssetMap[assetname] = asset;
                         }
                         else
                         {
                             ResourceLogger.logErr(string.Format("资源名 : {0}里有同名资源!Asset资源 : {1}添加失败!请优化取名,避免重名Asset!", AssetBundleName, assetname));
                         }
                     }
                 }
             }
             mIsAllAssetLoaded = true;
         }
     }
 }
Пример #24
0
 public override T loadAsset <T>(string assetname)
 {
     if (mIsReady)
     {
         if (mLoadedAssetMap.ContainsKey(assetname))
         {
             return(mLoadedAssetMap[assetname] as T);
         }
         else
         {
             if (AssetsPath == null)
             {
                 ResourceLogger.logErr(string.Format("资源名 : {0}资源丢失,不存在!", AssetBundleName));
                 return(null);
             }
             else
             {
                 // 图集需要全部加载才能加载到指定Sprite
                 // 暂时通过加载AssetBundle里所有的资源来加载查找指定sprite
                 if (typeof(T) == typeof(Sprite))
                 {
                     loadAllAsset <T>();
                     if (mLoadedAssetMap.ContainsKey(assetname))
                     {
                         return(mLoadedAssetMap[assetname] as T);
                     }
                     else
                     {
                         ResourceLogger.logErr(string.Format("找不到资源名 : {0}里 Asset资源 : {1}!", AssetBundleName, assetname));
                         return(null);
                     }
                 }
                 else
                 {
                     var assetpathes = AssetDatabase.GetAssetPathsFromAssetBundleAndAssetName(AssetBundleName, assetname);
                     if (assetpathes.Length == 1)
                     {
                         T asset = AssetDatabase.LoadAssetAtPath <T>(assetpathes[0]);
                         if (asset != null)
                         {
                             mLoadedAssetMap.Add(assetname, asset);
                             return(asset);
                         }
                         else
                         {
                             ResourceLogger.logErr(string.Format("找不到符合类型 : {0},资源名: {1},Asset : {2}资源!", typeof(T).GetType(), AssetBundleName, assetname));
                             return(null);
                         }
                     }
                     else if (assetpathes.Length > 1)
                     {
                         ResourceLogger.logErr(string.Format("资源名 : {0}里存在同名Asset : {}资源!请先纠正Asset取名!", AssetBundleName, assetname));
                         return(null);
                     }
                     else
                     {
                         ResourceLogger.logErr(string.Format("找不到资源名: {0},Asset : {1}资源!", AssetBundleName, assetname));
                         return(null);
                     }
                 }
             }
         }
     }
     else
     {
         ResourceLogger.logErr(string.Format("异常状态,AB资源:{0}未就绪就请求Asset资源:{1}", AssetBundleName, assetname));
         return(null);
     }
 }
    /// <summary>
    /// 加载指定Asset(可用上层访问Asset)
    /// Note:
    /// 因为没有绑定对象,仅用于临时访问Asset数据
    /// 访问过后无人引用的话会被回收
    /// </summary>
    /// <param name="assetname"></param>
    /// <returns></returns>
    public override T loadAsset <T>(string assetname)
    {
        if (mIsReady)
        {
            if (mLoadedAssetMap.ContainsKey(assetname))
            {
                return(mLoadedAssetMap[assetname] as T);
            }
            else
            {
                if (Bundle == null)
                {
                    ResourceLogger.logErr(string.Format("AB : {0}资源丢失,不存在!", AssetBundleName));
                    return(null);
                }
                else
                {
                    // 图集需要全部加载才能加载到指定Sprite
                    if (typeof(T) == typeof(Sprite))
                    {
                        if (!mIsAllAssetLoaded)
                        {
                            var allassets = Bundle.LoadAllAssets();
                            // foreach (var asset in allassets)
                            var count = allassets.Length;
                            for (int i = count - 1; i >= 0; i--)
                            {
                                //Note:
                                //只存储图集的Sprite Asset,不存储Texture2D
                                //现发现Sprite Asset有和Texture2D同名的情况存在
                                //TODO:解决Sprite Asset和Texture2D同名问题,满足可加载使用图集的Texture2D Asset
                                //暂时未存储Texture2D,要访问图集Texture2D可以通过Sprite.texture的形式访问
                                var asset = allassets[i];
                                if (mLoadedAssetMap.ContainsKey(asset.name) && asset is Texture2D)
                                {
                                    //ResourceLogger.logErr(string.Format("{0} : AB里存在同名Asset : {1}", AssetBundleName, asset.name));
                                    continue;
                                }
                                //这里把所有Asset都缓存,原来的写法只缓存sprite
                                //if (asset is Sprite)
                                //{
                                mLoadedAssetMap.Add(asset.name, asset);
                                //}

                                /*
                                 * else if (asset is Texture2D) //修改为同时存储 Sprite 和存储Texture2D对应的Sprite
                                 * {
                                 *  mLoadedAssetMap.Add(asset.name.ToLower(), (asset as Texture2D).toSprite());
                                 * }
                                 */
                            }
                            mIsAllAssetLoaded = true;
                        }

                        if (mLoadedAssetMap.ContainsKey(assetname))
                        {
                            return(mLoadedAssetMap[assetname] as T);
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        var asset = Bundle.LoadAsset <T>(assetname);
                        if (asset != null)
                        {
                            mLoadedAssetMap.Add(assetname, asset);
                            return(asset);
                        }
                        else
                        {
                            ResourceLogger.logErr(string.Format("AB:{0}里找不到Asset:{1}资源!", AssetBundleName, assetname));
                            return(null);
                        }
                    }
                }
            }
        }
        else
        {
            ResourceLogger.logErr(string.Format("异常状态,AB资源:{0}未就绪就请求Asset资源:{1}", AssetBundleName, assetname));
            return(null);
        }
    }