Esempio n. 1
0
        static void loadAsync(string[] assetPaths, ResourcesLoadingLocation resourcesLoadingLocation, bool isLoadScene, Func <string, AsyncOperation>[] sceneAsyncRequestFuncs, System.Action <bool, float, string, T[]> asyncAction)
        {
            // 如果意图加载异步,但是场景场景异步请求回调数量和输入的场景资源路径数量不一样时
            // 直接返回错误
            if (isLoadScene && (assetPaths == null || sceneAsyncRequestFuncs == null || assetPaths.Length != sceneAsyncRequestFuncs.Length))
            {
                asyncAction(false, 1, null, null);
                ResourcesManager.NextFrame(() => asyncAction(true, 1, ResourcesManager.KSwordKitName + ": 加载失败!视图加载异步,但是提供的场景异步请求回调数量和输入的场景资源路径数量不一致。\n请检查参数 `assetPaths` 和参数 `scnenAsyncRequestFuncs`。\n如不明白该API含义,请查阅相关文档。", null));
                return;
            }

            int    c         = assetPaths.Length;
            int    cc        = 0;
            string error     = null;
            var    objs      = new T[c];
            var    _progress = 0f;

            for (var i = 0; i < c; i++)
            {
                var index = i;
                loadAsync(assetPaths[i], resourcesLoadingLocation, isLoadScene, isLoadScene? sceneAsyncRequestFuncs[i] : null, (isdone, progress, _error, obj) => {
                    if (isdone)
                    {
                        cc++;
                        objs[index] = obj;
                        if (!string.IsNullOrEmpty(_error))
                        {
                            if (string.IsNullOrEmpty(error))
                            {
                                error = _error;
                            }
                            else
                            {
                                error += "\n" + _error;
                            }
                        }

                        if (c == cc)
                        {
                            if (_progress == 1f)
                            {
                                asyncAction(true, 1, error, objs);
                            }
                            else
                            {
                                asyncAction(false, 1, null, null);
                                ResourcesManager.NextFrame(() => {
                                    asyncAction(true, 1, error, objs);
                                });
                            }
                        }
                        return;
                    }

                    _progress = (float)cc / c + 1f / (float)c * progress;
                    asyncAction(false, _progress, null, null);
                });
            }
        }
 static void WaitWhile(Func <bool> waitFunc, System.Action completedAction)
 {
     if (waitFunc())
     {
         completedAction();
     }
     else
     {
         ResourcesManager.NextFrame(() =>
         {
             WaitWhile(waitFunc, completedAction);
         });
     }
 }
        /// <summary>
        /// 加载依赖
        /// </summary>
        /// <param name="assetBundleDependencies"></param>
        /// <param name="asyncAction"></param>
        public static void LoadDependencies(string[] assetBundleDependencies, System.Action <bool, float, string> asyncAction)
        {
            // 资源包对象须存在
            if (_ResourcePackage == null)
            {
                if (asyncAction != null)
                {
                    asyncAction(false, 1, null);
                    ResourcesManager.NextFrame(() => asyncAction(true, 1, ResourcesManager.KSwordKitName + ": 请先调用 SetResourcePackage 方法设置资源包"));
                }
                return;
            }
            var maxc = assetBundleDependencies.Length;

            if (maxc == 0)
            {
                if (asyncAction != null)
                {
                    asyncAction(false, 1, null);
                    ResourcesManager.NextFrame(() => asyncAction(true, 1, null));
                }
                return;
            }
            var    currc = 0;
            string error = string.Empty;

            // 检测是否加载完成
            System.Action doneAction = () => {
                if (maxc == currc)
                {
                    ResourcesManager.NextFrame(() => asyncAction(true, 1, string.IsNullOrEmpty(error) ? null: error));
                }
            };
            for (var i = 0; i < maxc; i++)
            {
                var abname = assetBundleDependencies[i];
                if (ResourcesManager.Instance.AssetbundleName_AssetBundlePathDic.ContainsKey(abname))
                {
                    var rm = ResourcesManager.Instance.AssetbundleName_AssetBundlePathDic[abname];
                    if (rm.AssetBundle == null)
                    {
                        rm.AsyncLoad((isdone, progress, _error, ab) => {
                            if (isdone)
                            {
                                currc++;
                                if (!string.IsNullOrEmpty(_error))
                                {
                                    error += "\n" + _error;
                                }
                                doneAction();
                                return;
                            }
                            asyncAction(false, (float)currc / maxc + (float)1 / maxc * progress, null);
                        });
                    }
                    else
                    {
                        currc++;
                        asyncAction(false, (float)currc / maxc, null);
                        doneAction();
                    }
                }
                else
                {
                    currc++;
                    error += "\n加载资源失败!AssetBundleName '" + abname + "' 不存在。";
                    asyncAction(false, (float)currc / maxc, null);
                    doneAction();
                }
            }
        }
        static void loadAsync(string assetPath, ResourcesLoadingLocation resourcesLoadingLocation, bool isLoadScene, Func <string, AsyncOperation> sceneAsyncRequestFunc, System.Action <bool, float, string, T> asyncAction)
        {
            // 总共需要3步
            // 1. 初始化资源包,只需执行一次
            // 2. 加载资源包
            // 3. 从资源包中加载资源

            // 资源包对象须存在
            if (_ResourcePackage == null)
            {
                if (asyncAction != null)
                {
                    asyncAction(false, 1, null, null);
                    ResourcesManager.NextFrame(() => asyncAction(true, 1, ResourcesManager.KSwordKitName + ": 请先调用 SetResourcePackage 方法设置资源包", null));
                }
                return;
            }
            // 检查缓存内容, 缓存中存在时,加载缓存中的资源
            if (CacheDic.ContainsKey(assetPath))
            {
                if (asyncAction != null)
                {
                    asyncAction(false, 1, null, null);
                    ResourcesManager.NextFrame(() => asyncAction(true, 1, null, CacheDic[assetPath]));
                }

                return;
            }
            // 检查资源是否存在
            if (ResourcesManager.Instance.ResourceObjectPath_ResourceObjectDic.ContainsKey(assetPath))
            {
                var ro = ResourcesManager.Instance.ResourceObjectPath_ResourceObjectDic[assetPath];
                var rm = ResourcesManager.Instance.AssetbundleName_AssetBundlePathDic[ro.AssetBundleName];
                if (ro.IsScene && !isLoadScene)
                {
                    asyncAction(false, 1, null, null);
                    ResourcesManager.NextFrame(
                        () => asyncAction(
                            true,
                            1,
                            ResourcesManager.KSwordKitName + ": 资源加载失败! 该资源是场景资源,但是请求加载非场景资源,因此无法加载! 请使用 `KSwordKit.Contents.ResourcesManagement.ResourcesManager.LoadSceneAsync` 相关的API再次尝试。\n参数 assetPath=" + assetPath,
                            null
                            )
                        );
                    return;
                }
                if (!ro.IsScene && isLoadScene)
                {
                    asyncAction(false, 1, null, null);
                    ResourcesManager.NextFrame(
                        () => asyncAction(
                            true,
                            1,
                            ResourcesManager.KSwordKitName + ": 资源加载失败! 该资源不是场景资源,但是请求加载场景资源,因此无法加载! 请使用 `KSwordKit.Contents.ResourcesManagement.ResourcesManager.LoadAssetAsync` 相关的API再次尝试。\n参数 assetPath=" + assetPath,
                            null
                            )
                        );
                    return;
                }
                // 根据资源加载位置的不同采取不同的加载策略
                switch (resourcesLoadingLocation)
                {
                // 使用 Resources.LoadAsync
                case ResourcesLoadingLocation.Resources:
                    if (ro.IsScene && isLoadScene)
                    {
                        if (!_TypeIsSceneInfo)
                        {
                            Debug.LogWarning(ResourcesManager.KSwordKitName + ": 泛型应当提供类型 `KSwordKit.Contents.ResourcesManagement.SceneInfo`;当前操作将以默认方式继续执行。");
                        }
                        T    _sceneinfo       = null;
                        bool isset__sceneinfo = false;
                        _loader.StartCoroutine(ro.AsyncLoadScene(assetPath, sceneAsyncRequestFunc, (isdone, progress, error, sceneinfo) =>
                        {
                            if (isdone)
                            {
                                asyncAction(isdone, progress, error, _sceneinfo);
                                return;
                            }

                            if (!isset__sceneinfo)
                            {
                                isset__sceneinfo = true;
                                if (_TypeIsSceneInfo)     // 只有在泛型类型为 SceneInfo 时,在回调中的参数 `SceneInfo` 数据才有效。
                                {
                                    _sceneinfo = sceneinfo as T;
                                }
                            }

                            asyncAction(isdone, progress, error, _sceneinfo);
                        }));
                        return;
                    }


                    _loadResourcesByResources(assetPath, asyncAction);
                    break;

                // 其他路径下都使用同样的办法加载资源
                // 加载器只处理本地资源
                // 当使用远程资源时,资源管理器会在需要更新的时候,先更新远程资源到本地,进而保证加载器加载的永远是最新的资源包。
                case ResourcesLoadingLocation.StreamingAssetsPath:
                case ResourcesLoadingLocation.PersistentDataPath:
                case ResourcesLoadingLocation.RemotePath:

                    // 加载资源
                    System.Action abloadedAction = () =>
                    {
                        float _progress = 0;
                        if (ro.IsScene && isLoadScene)
                        {
                            if (!_TypeIsSceneInfo)
                            {
                                Debug.LogWarning(ResourcesManager.KSwordKitName + ": 应当提供类型 `KSwordKit.Contents.ResourcesManagement.SceneInfo`;当前操作将以默认方式继续加载。");
                            }
                            T    _sceneinfo       = null;
                            bool isset__sceneinfo = false;
                            _loader.StartCoroutine(ro.AsyncLoadScene(assetPath, sceneAsyncRequestFunc, (isdone, progress, error, sceneinfo) =>
                            {
                                if (isdone)
                                {
                                    asyncAction(isdone, progress, error, _sceneinfo);
                                    return;
                                }

                                if (!isset__sceneinfo)
                                {
                                    isset__sceneinfo = true;
                                    if (_TypeIsSceneInfo)     // 只有在泛型类型为 SceneInfo 时,在回调中的参数 `SceneInfo` 数据才有效。
                                    {
                                        _sceneinfo = sceneinfo as T;
                                    }
                                }

                                asyncAction(isdone, progress, error, _sceneinfo);
                            }));
                            return;
                        }

                        _loader.StartCoroutine(ro.AsyncLoad(assetPath, rm.AssetBundle, (isdone, progress, error, obj) =>
                        {
                            if (isdone)
                            {
                                System.Action action = () =>
                                {
                                    string asyncLoadAbr_error = null;
                                    try
                                    {
                                        T t = null;
                                        if (_TypeIsSprite)
                                        {
                                            var t2d = obj as Texture2D;
                                            t       = Sprite.Create(t2d, new Rect(0, 0, t2d.width, t2d.height), Vector2.zero) as T;
                                        }
                                        else
                                        {
                                            t = obj as T;
                                        }

                                        if (t != null)
                                        {
                                            // 资源加载成功后,存入资源缓存中
                                            CacheDic[assetPath] = t;
                                            asyncAction(true, 1, null, t);
                                        }
                                        else
                                        {
                                            asyncLoadAbr_error = ResourcesManager.KSwordKitName + ": 资源加载成功,但该资源无法转换为 " + _Type.FullName + " 类型。\nassetPath=" + assetPath;
                                            asyncAction(true, 1, asyncLoadAbr_error, null);
                                        }
                                    }
                                    catch (System.Exception e)
                                    {
                                        asyncLoadAbr_error = ResourcesManager.KSwordKitName + ": 资源加载成功,但该资源无法转换为 " + _Type.FullName + " 类型, " + e.Message + "\nassetPath=" + assetPath;;
                                        asyncAction(true, 1, asyncLoadAbr_error, null);
                                    }
                                };
                                if (_progress != 1)
                                {
                                    if (asyncAction != null)
                                    {
                                        asyncAction(false, 1, error, null);
                                    }
                                    ResourcesManager.NextFrame(action);
                                }
                                else
                                {
                                    action();
                                }

                                return;
                            }

                            _progress = 2f / 3f + 1f / 3f * progress;
                            if (asyncAction != null && _progress > 2f / 3f)
                            {
                                asyncAction(false, _progress, error, null);
                            }
                        }));
                    };

                    if (rm.AssetBundle == null)
                    {
                        // 加载资源包
                        rm.AsyncLoadTimeout = timeoutIfCanBeApplied;
                        _loader.StartCoroutine(rm.AsyncLoad((isdone, progress, error, obj) =>
                        {
                            if (isdone)
                            {
                                if (string.IsNullOrEmpty(error))
                                {
                                    if (asyncAction != null)
                                    {
                                        asyncAction(false, 2f / 3f, null, null);
                                    }
                                    abloadedAction();
                                }
                                else if (asyncAction != null)
                                {
                                    asyncAction(false, 1, error, null);
                                }

                                return;
                            }
                            if (asyncAction != null)
                            {
                                asyncAction(false, 1f / 3f + 1f / 3f * progress, error, null);
                            }
                        }));
                    }
                    else
                    {
                        abloadedAction();
                    }
                    break;
                }
            }
            else
            {
                if (asyncAction != null)
                {
                    asyncAction(false, 1, null, null);
                    ResourcesManager.NextFrame(() => asyncAction(true, 1, ResourcesManager.KSwordKitName + ": 资源不存在!请检查参数 assetPath 是否正确,assetPath=" + assetPath, null));
                }
            }
        }
Esempio n. 5
0
        /// <summary>
        /// 异步加载
        /// </summary>
        /// <param name="path">输入的路径</param>
        /// <param name="assetBundle">资源包</param>
        /// <param name="asyncAction">回调动作</param>
        /// <returns>协程</returns>
        public IEnumerator AsyncLoad(string path, AssetBundle assetBundle, System.Action <bool, float, string, UnityEngine.Object> asyncAction)
        {
            // 如果该资源已经加载过了,程序返回该资源的加载情况
            if (asyncloaded)
            {
                if (asyncLoadAbr_isdone)
                {
                    asyncAction(false, 1, null, null);
                    if (!string.IsNullOrEmpty(asyncLoad_error))
                    {
                        ResourcesManager.NextFrame(() => asyncAction(asyncLoadAbr_isdone, 1, asyncLoad_error, null));
                    }
                    else
                    {
                        ResourcesManager.NextFrame(() => asyncAction(asyncLoadAbr_isdone, 1, null, Object));
                    }
                }
                else
                {
                    asyncLoadAbrEvent += asyncAction;
                }
                yield break;
            }

            // 标记该资源已被加载
            asyncloaded     = true;
            asyncLoad_error = null;
            // 设置回调函数
            asyncLoadAbrEvent += asyncAction;
            // 如果是场景资源返回错误
            if (IsScene)
            {
                asyncLoadAbrEvent(false, 1, null, null);
                yield return(null);

                asyncLoad_error = ResourcesManager.KSwordKitName + ": 资源加载失败! 该资源是场景资源,无法加载! 请使用请检查参数 assetPath 是否正确, assetPath=" + path;
                asyncLoadAbrEvent(true, 1, asyncLoad_error, null);
                asyncLoadAbrEvent -= asyncAction;

                asyncLoadAbr_isdone = true;
                yield break;
            }

            // 开始加载
            var assetBundleRequest = assetBundle.LoadAssetAsync(ObjectName);

            while (!assetBundleRequest.isDone)
            {
                asyncLoadAbrEvent(false, assetBundleRequest.progress, null, null);
                yield return(null);
            }
            // 加载完成后更新进度信息
            if (assetBundleRequest.progress != 1)
            {
                asyncLoadAbrEvent(false, 1, null, null);
                yield return(null);
            }
            // 检查加载完成情况
            if (assetBundleRequest.asset == null)
            {
                asyncLoad_error = ResourcesManager.KSwordKitName + ": 资源加载失败! 请检查参数 assetPath 是否正确, assetPath=" + path;
                asyncLoadAbrEvent(true, 1, asyncLoad_error, null);
            }
            else
            {
                try
                {
                    if (assetBundleRequest.asset != null)
                    {
                        // 资源加载成功后,存入资源缓存中
                        Object = assetBundleRequest.asset;
                        asyncLoadAbrEvent(true, 1, null, Object);
                    }
                    else
                    {
                        asyncLoad_error = ResourcesManager.KSwordKitName + ": 资源加载失败! 请检查参数 assetPath 是否正确, assetPath=" + path;
                        asyncLoadAbrEvent(true, 1, asyncLoad_error, null);
                    }
                }
                catch (System.Exception e)
                {
                    asyncLoad_error = ResourcesManager.KSwordKitName + ": 资源加载失败! 请检查参数 assetPath 是否正确, assetPath=" + path;
                    asyncLoadAbrEvent(true, 1, asyncLoad_error, null);
                }
            }
            asyncLoadAbrEvent  -= asyncAction;
            asyncLoadAbr_isdone = true;
        }
Esempio n. 6
0
        /// <summary>
        /// 加载资源包方法
        /// </summary>
        /// <param name="action">回调动作</param>
        /// <returns>协程</returns>
        public IEnumerator AsyncLoad(System.Action <bool, float, string, AssetBundle> action)
        {
            // 如果该资源已经加载过了,程序返回该资源的加载情况
            if (asyncloaded)
            {
                if (isDone)
                {
                    action(false, 1, null, null);
                    ResourcesManager.NextFrame(() => action(isDone, 1, error, AssetBundle));
                }
                else
                {
                    LoadingStatusEvent += action;
                }

                yield break;
            }

            // 标记该资源已被加载
            asyncloaded = true;
            // 设置回调函数
            LoadingStatusEvent += action;
            // 先加载依赖
            float dc = Dependencies.Count;
            float cc = 0;

            for (var i = 0; i < dc; i++)
            {
                yield return(ResourcesManager.Instance.AssetbundleName_AssetBundlePathDic[Dependencies[i]].AsyncLoad((isdone, progress, _error, obj) =>
                {
                    if (!string.IsNullOrEmpty(error))
                    {
                        cc++;
                        return;
                    }
                    if (isdone)
                    {
                        error = _error;
                        cc++;
                        return;
                    }
                    LoadingStatusEvent(false, 0.5f * (cc / dc + (1 / dc) * progress), null, null);
                }));
            }
            // 等待所有依赖加载完毕
            while (cc != dc)
            {
                yield return(null);
            }
            // 如果加载依赖过程中发生了错误,则程序终止,返回错误信息。
            if (!string.IsNullOrEmpty(error))
            {
                LoadingStatusEvent(false, 1, error, null);
                yield break;
            }
            // 所有依赖全部顺利加载完毕后,开始加载自身
            var rootDir         = System.IO.Path.Combine(ResourcesManager.Instance.GetResourcesFileRootDirectory(), ResourcesManager.ResourceRootDirectoryName);
            var unityWebRequest = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle("file://" + System.IO.Path.Combine(rootDir, AssetBundlePath));

            unityWebRequest.timeout = AsyncLoadTimeout;
            var op = unityWebRequest.SendWebRequest();

            while (!op.isDone)
            {
                isDone = false;
                LoadingStatusEvent(false, 0.5f + 0.5f * op.progress, null, null);
                yield return(null);
            }

            // 加载完成后更新进度信息
            if (op.progress != 1f)
            {
                LoadingStatusEvent(false, 1, null, null);
                yield return(null);
            }
            // 检查加载完成情况
            if (string.IsNullOrEmpty(unityWebRequest.error))
            {
                try
                {
                    // 尝试加载将AssetBundle加载到内存中
                    AssetBundle ab = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(unityWebRequest);

                    if (ab != null)
                    {
                        AssetBundle = ab;
                        LoadingStatusEvent(true, 1, null, ab);
                    }
                    else
                    {
                        error = ResourcesManager.KSwordKitName + ": 加载资源包失败!\nassetBunbleName=" + AssetBundleName + "\nAssetBundlePath=" + AssetBundlePath + "\nurl=" + unityWebRequest.url;
                        LoadingStatusEvent(true, 1, error, null);
                    }
                }
                catch (System.Exception e)
                {
                    error = ResourcesManager.KSwordKitName + ": 加载资源包失败!" + e.Message + "\nassetBunbleName=" + AssetBundleName + "\nAssetBundlePath=" + AssetBundlePath + "\nurl=" + unityWebRequest.url;
                    LoadingStatusEvent(true, 1, error, null);
                }
            }
            else
            {
                error = ResourcesManager.KSwordKitName + ": 加载资源包失败!" + unityWebRequest.error + "\nassetBunbleName=" + AssetBundleName + "\nAssetBundlePath=" + AssetBundlePath + "\nurl=" + unityWebRequest.url;
                LoadingStatusEvent(true, 1, error, null);
            }

            LoadingStatusEvent -= action;
            isDone              = true;
        }