/// <summary>
        /// 异步加载资源
        /// </summary>
        /// <param name="assetName">资源名称</param>
        /// <param name="callBack">回调函数</param>
        /// <returns>加载进度</returns>
        public IProgress LoadAsync <T>(string assetName, System.Action <T> callBack) where T : Object
        {
            if (IsResources(assetName))
            {
                assetName = assetName.Substring(4, assetName.Length - 4);
                var request = Resources.LoadAsync(assetName);

                SingleTask task = new SingleTask(() =>
                {
                    return(request.isDone);
                });
                task.Then(() =>
                {
                    callBack.Invoke(request.asset as T);
                    return(true);
                });
                task.Start();
                return(null);
            }

            else
            {
                assetName = Path2RealPath(assetName);
                return(m_LoadHelper.LoadAsync <T>(assetName, callBack));
            }
        }
        public IProgress LoadAsync <T>(string assetName, System.Action <T> callback) where T : Object
        {
            var temp = Utility.Text.SplitPathName(assetName);

            return(GetAssetBundleAsync(temp[0], (ab) =>
            {
                var request = ab.LoadAssetAsync(temp[1]);
                SingleTask task = new SingleTask(() => { return request.isDone; });
                task.Then(() => { callback(request.asset as T); return true; });
                GameEntry.GetModule <TaskManager>().StartTask(task);
            }));
        }
        /// <summary>
        /// 异步获取一组ab包
        /// </summary>
        /// <param name="path"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        private IProgress LoadAssetBundlesAsync(string path, Action <IEnumerable <AssetBundle> > callback)
        {
            List <IProgress> progresses = new List <IProgress>();

            path = Path2Key(path);

            List <AssetBundle> assetBundles = new List <AssetBundle>();

            // top层
            var abProgress = LoadAssetBundleAsync(path, (ab) =>
            {
                assetBundles.Add(ab);
            });

            progresses.Add(abProgress);
            int abCount = 1;

            // 其它层
            string directoryPath = m_ABPath + "/" + path;
            var    subDirectory  = new System.IO.DirectoryInfo(directoryPath);

            if (subDirectory.Exists)
            {
                var abFiles = subDirectory.GetFiles($"*{m_Variant}", System.IO.SearchOption.AllDirectories);

                int startIndex = m_ABPath.Length + 1;
                abCount += abFiles.Length;
                foreach (var item in abFiles)
                {
                    var abPath = item.FullName.Substring(startIndex);

                    var progress = LoadAssetBundleAsync(abPath, (ab) =>
                    {
                        assetBundles.Add(ab);
                    });
                    progresses.Add(abProgress);
                }
            }

            SingleTask singleTask = new SingleTask(() => { return(assetBundles.Count == abCount); });

            singleTask.Then(() => { callback(assetBundles); return(true); });
            singleTask.Start();

            return(new MultiProgress(progresses.ToArray()));
        }
        /// <summary>
        /// 同步加载一组资源
        /// </summary>
        /// <typeparam name="T">资源类型</typeparam>
        /// <param name="path">资源路径</param>
        /// <param name="isTopOnly">是否是仅加载本层级的资源</param>
        /// <returns>资源</returns>
        public IProgress LoadAllSync <T>(string path, bool isTopOnly, Action <T[]> callback) where T : UnityEngine.Object
        {
            if (isTopOnly)
            {
                return(LoadAssetBundleAsync(path, (ab) =>
                {
                    AssetBundleRequest request = ab.LoadAllAssetsAsync <T>();
                    SingleTask task = new SingleTask(() =>
                    {
                        return request.isDone;
                    });
                    task.Then(() => { callback(request.allAssets.Convert <T>()); return true; });
                }));
            }
            else
            {
                List <T> assets = new List <T>();

                DynamicMultiProgress dynamicProgress = new DynamicMultiProgress(2);
                var assetBundlesProgress             = LoadAssetBundlesAsync(path, OnAssetBundleLoadComplate);

                return(dynamicProgress);

                void OnAssetBundleLoadComplate(IEnumerable <AssetBundle> assetBundles)
                {
                    List <IProgress> progresses = new List <IProgress>();

                    foreach (var ab in assetBundles)
                    {
                        var        request = ab.LoadAllAssetsAsync <T>();
                        SingleTask task    = new SingleTask(() =>
                        {
                            return(request.isDone);
                        });
                        task.Then(() => { assets.AddRange(request.allAssets.Convert <T>()); return(true); });
                        progresses.Add(new SingleResProgress(request));
                    }
                    dynamicProgress.Add(new MultiProgress(progresses.ToArray()));
                }
            }
        }
        /// <summary>
        /// 异步加载资源
        /// </summary>
        /// <typeparam name="T">资源类型</typeparam>
        /// <param name="assetName">资源名称(完整名称,加路径及后缀名)</param>
        /// <param name="callback">回调函数</param>
        /// <returns>加载进度</returns>
        public IProgress LoadAsync <T>(string assetName, Action <T> callback) where T : UnityEngine.Object
        {
            var temp = Utility.Text.SplitPathName(assetName);

            DynamicMultiProgress progress = new DynamicMultiProgress(2, 0.9f, 0.1f);

            var abProgress = LoadAssetBundleAsync(temp[0], (ab) =>
            {
                var request     = ab.LoadAssetAsync(temp[1]);
                SingleTask task = new SingleTask(() =>
                {
                    return(request.isDone);
                });
                task.Then(() => { callback(request.asset as T); return(true); });
                task.Start();

                SingleResProgress resProgress = new SingleResProgress(request);
                progress.Add(resProgress);
            });

            progress.Add(abProgress);

            return(progress);
        }
        public IProgress LoadAsync <T>(string assetName, System.Action <T> callback) where T : Object
        {
            var temp = Utility.Text.SplitPathName(assetName);

            DynamicMultiProgress progress = new DynamicMultiProgress(2);

            var abProgress = GetAssetBundleAsync(temp[0], (ab) =>
            {
                var request     = ab.LoadAssetAsync(temp[1]);
                SingleTask task = new SingleTask(() =>
                {
                    return(request.isDone);
                });
                task.Then(() => { callback(request.asset as T); return(true); });
                GameEntry.GetModule <TaskManager>().StartTask(task);

                SingleResProgress resProgress = new SingleResProgress(request);
                progress.Add(resProgress);
            });

            progress.Add(abProgress);

            return(progress);
        }