Ejemplo n.º 1
0
        /// <summary>
        /// 主线程等待异步操作完毕
        /// </summary>
        public override void WaitForAsyncComplete()
        {
            _isWaitForAsyncComplete = true;

            int frame = 1000;

            while (true)
            {
                // 保险机制
                // 注意:如果需要从WEB端下载资源,可能会触发保险机制!
                frame--;
                if (frame == 0)
                {
                    if (_isShowWaitForAsyncError == false)
                    {
                        _isShowWaitForAsyncError = true;
                        YooLogger.Error($"WaitForAsyncComplete failed ! BundleName : {MainBundleInfo.BundleName} States : {Status}");
                    }
                    break;
                }

                // 驱动流程
                Update();

                // 完成后退出
                if (IsDone())
                {
                    break;
                }
            }
        }
Ejemplo n.º 2
0
        private static AssetInfo ConvertLocationToAssetInfo(string location, System.Type assetType)
        {
            DebugCheckLocation(location);
            string     assetPath  = _locationServices.ConvertLocationToAssetPath(location);
            PatchAsset patchAsset = _bundleServices.TryGetPatchAsset(assetPath);

            if (patchAsset != null)
            {
                AssetInfo assetInfo = new AssetInfo(patchAsset, assetType);
                return(assetInfo);
            }
            else
            {
                string error;
                if (string.IsNullOrEmpty(location))
                {
                    error = $"The location is null or empty !";
                }
                else
                {
                    error = $"The location is invalid : {location}";
                }
                YooLogger.Error(error);
                AssetInfo assetInfo = new AssetInfo(error);
                return(assetInfo);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 异步卸载子场景
        /// </summary>
        public UnloadSceneOperation UnloadAsync()
        {
            // 如果句柄无效
            if (IsValid == false)
            {
                string error     = $"{nameof(SceneOperationHandle)} is invalid.";
                var    operation = new UnloadSceneOperation(error);
                OperationSystem.StartOperaiton(operation);
                return(operation);
            }

            // 如果是主场景
            if (IsMainScene())
            {
                string error = $"Cannot unload main scene. Use {nameof(YooAssets.LoadSceneAsync)} method to change the main scene !";
                YooLogger.Error(error);
                var operation = new UnloadSceneOperation(error);
                OperationSystem.StartOperaiton(operation);
                return(operation);
            }

            // 卸载子场景
            Scene sceneObject = SceneObject;

            AssetSystem.UnloadSubScene(Provider);
            {
                var operation = new UnloadSceneOperation(sceneObject);
                OperationSystem.StartOperaiton(operation);
                return(operation);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 获取调试信息
        /// </summary>
        internal static void GetDebugReport(DebugReport report)
        {
            if (report == null)
            {
                YooLogger.Error($"{nameof(DebugReport)} is null");
            }

            AssetSystem.GetDebugReport(report);
        }
Ejemplo n.º 5
0
        public override void Update()
        {
#if UNITY_EDITOR
            if (IsDone)
            {
                return;
            }

            if (Status == EStatus.None)
            {
                Status = EStatus.Loading;
            }

            // 1. 加载资源对象
            if (Status == EStatus.Loading)
            {
                LoadSceneParameters loadSceneParameters = new LoadSceneParameters();
                loadSceneParameters.loadSceneMode = SceneMode;
                _asyncOp = UnityEditor.SceneManagement.EditorSceneManager.LoadSceneAsyncInPlayMode(MainAssetInfo.AssetPath, loadSceneParameters);
                if (_asyncOp != null)
                {
                    _asyncOp.allowSceneActivation = true;
                    _asyncOp.priority             = _priority;
                    Status = EStatus.Checking;
                }
                else
                {
                    Status    = EStatus.Fail;
                    LastError = $"Failed to load scene : {MainAssetInfo.AssetPath}";
                    YooLogger.Error(LastError);
                    InvokeCompletion();
                }
            }

            // 2. 检测加载结果
            if (Status == EStatus.Checking)
            {
                if (_asyncOp.isDone)
                {
                    SceneObject = SceneManager.GetSceneAt(SceneManager.sceneCount - 1);
                    if (SceneObject.IsValid() && _activateOnLoad)
                    {
                        SceneManager.SetActiveScene(SceneObject);
                    }

                    Status = SceneObject.IsValid() ? EStatus.Success : EStatus.Fail;
                    if (Status == EStatus.Fail)
                    {
                        LastError = $"The loaded scene is invalid : {MainAssetInfo.AssetPath}";
                        YooLogger.Error(LastError);
                    }
                    InvokeCompletion();
                }
            }
#endif
        }
Ejemplo n.º 6
0
 /// <summary>
 /// 创建包裹下载器
 /// </summary>
 public override PackageDownloaderOperation CreatePackageDownloader(int downloadingMaxNumber, int failedTryAgain)
 {
     if (Status == EOperationStatus.Succeed)
     {
         List <BundleInfo> downloadList = GetDownloadList();
         var operation = new PackageDownloaderOperation(downloadList, downloadingMaxNumber, failedTryAgain);
         return(operation);
     }
     else
     {
         YooLogger.Error($"{nameof(UpdatePackageOperation)} status is failed !");
         var operation = new PackageDownloaderOperation(null, downloadingMaxNumber, failedTryAgain);
         return(operation);
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// 解析并保存远端请求的补丁清单
        /// </summary>
        private bool ParseAndSaveRemotePatchManifest(int updateResourceVersion, string content)
        {
            try
            {
                var remotePatchManifest = PatchManifest.Deserialize(content);
                _impl.SetLocalPatchManifest(remotePatchManifest);

                YooLogger.Log("Save remote patch manifest file.");
                string savePath = PathHelper.MakePersistentLoadPath(YooAssetSettingsData.GetPatchManifestFileName(updateResourceVersion));
                PatchManifest.Serialize(savePath, remotePatchManifest);
                return(true);
            }
            catch (Exception e)
            {
                YooLogger.Error(e.ToString());
                return(false);
            }
        }
Ejemplo n.º 8
0
 /// <summary>
 /// 查询是否为验证文件
 /// 注意:被收录的文件完整性是绝对有效的
 /// </summary>
 public static bool ContainsVerifyFile(string hash)
 {
     if (_cachedHashList.ContainsKey(hash))
     {
         string filePath = SandboxHelper.MakeCacheFilePath(hash);
         if (File.Exists(filePath))
         {
             return(true);
         }
         else
         {
             string bundleName = _cachedHashList[hash];
             _cachedHashList.Remove(hash);
             YooLogger.Error($"Cache file is missing : {bundleName} Hash : {hash}");
             return(false);
         }
     }
     else
     {
         return(false);
     }
 }
Ejemplo n.º 9
0
        /// <summary>
        /// 映射为资源路径
        /// </summary>
        public string MappingToAssetPath(string location)
        {
            if (string.IsNullOrEmpty(location))
            {
                YooLogger.Error("Failed to mapping location to asset path, The location is null or empty.");
                return(string.Empty);
            }

            if (_locationToLower)
            {
                location = location.ToLower();
            }

            if (AssetPathMapping.TryGetValue(location, out string assetPath))
            {
                return(assetPath);
            }
            else
            {
                YooLogger.Warning($"Failed to mapping location to asset path : {location}");
                return(string.Empty);
            }
        }
Ejemplo n.º 10
0
        public override void Update()
        {
#if UNITY_EDITOR
            if (IsDone)
            {
                return;
            }

            if (Status == EStatus.None)
            {
                // 检测资源文件是否存在
                string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
                if (string.IsNullOrEmpty(guid))
                {
                    Status    = EStatus.Fail;
                    LastError = $"Not found asset : {MainAssetInfo.AssetPath}";
                    YooLogger.Error(LastError);
                    InvokeCompletion();
                    return;
                }

                Status = EStatus.Loading;

                // 注意:模拟异步加载效果提前返回
                if (IsWaitForAsyncComplete == false)
                {
                    return;
                }
            }

            // 1. 加载资源对象
            if (Status == EStatus.Loading)
            {
                if (MainAssetInfo.AssetType == null)
                {
                    AllAssetObjects = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
                }
                else
                {
                    UnityEngine.Object[]      findAssets = UnityEditor.AssetDatabase.LoadAllAssetRepresentationsAtPath(MainAssetInfo.AssetPath);
                    List <UnityEngine.Object> result     = new List <Object>(findAssets.Length);
                    foreach (var findAsset in findAssets)
                    {
                        if (MainAssetInfo.AssetType.IsAssignableFrom(findAsset.GetType()))
                        {
                            result.Add(findAsset);
                        }
                    }
                    AllAssetObjects = result.ToArray();
                }
                Status = EStatus.Checking;
            }

            // 2. 检测加载结果
            if (Status == EStatus.Checking)
            {
                Status = AllAssetObjects == null ? EStatus.Fail : EStatus.Success;
                if (Status == EStatus.Fail)
                {
                    if (MainAssetInfo.AssetType == null)
                    {
                        LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : null";
                    }
                    else
                    {
                        LastError = $"Failed to load sub assets : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
                    }
                    YooLogger.Error(LastError);
                }
                InvokeCompletion();
            }
#endif
        }
Ejemplo n.º 11
0
        /// <summary>
        /// 轮询更新
        /// </summary>
        public override void Update()
        {
            if (_steps == ESteps.Done)
            {
                return;
            }

            if (_steps == ESteps.None)
            {
                if (MainBundleInfo.IsInvalid)
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = $"The bundle info is invalid : {MainBundleInfo.BundleName}";
                    YooLogger.Error(LastError);
                    return;
                }

                if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
                {
                    _steps  = ESteps.LoadFile;
                    _webURL = MainBundleInfo.GetStreamingLoadPath();
                }
                else
                {
                    throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
                }
            }

            // 1. 从服务器或缓存中获取AssetBundle文件
            if (_steps == ESteps.LoadFile)
            {
                string hash = StringUtility.RemoveExtension(MainBundleInfo.Hash);
                _webRequest = UnityWebRequestAssetBundle.GetAssetBundle(_webURL, Hash128.Parse(hash));
                _webRequest.SendWebRequest();
                _steps = ESteps.CheckFile;
            }

            // 2. 检测获取的AssetBundle文件
            if (_steps == ESteps.CheckFile)
            {
                if (_webRequest.isDone == false)
                {
                    return;
                }

#if UNITY_2020_1_OR_NEWER
                if (_webRequest.result != UnityWebRequest.Result.Success)
#else
                if (_webRequest.isNetworkError || _webRequest.isHttpError)
#endif
                {
                    YooLogger.Warning($"Failed to get asset bundle form web : {_webURL} Error : {_webRequest.error}");
                    _steps    = ESteps.TryLoad;
                    _tryTimer = 0;
                }
                else
                {
                    CacheBundle = DownloadHandlerAssetBundle.GetContent(_webRequest);
                    if (CacheBundle == null)
                    {
                        _steps    = ESteps.Done;
                        Status    = EStatus.Failed;
                        LastError = $"AssetBundle file is invalid : {MainBundleInfo.BundleName}";
                        YooLogger.Error(LastError);
                    }
                    else
                    {
                        _steps = ESteps.Done;
                        Status = EStatus.Succeed;
                    }
                }
            }

            // 3. 如果获取失败,重新尝试
            if (_steps == ESteps.TryLoad)
            {
                _tryTimer += Time.unscaledDeltaTime;
                if (_tryTimer > 1f)
                {
                    _webRequest.Dispose();
                    _webRequest = null;
                    _steps      = ESteps.LoadFile;
                }
            }
        }
Ejemplo n.º 12
0
        public override void Update()
        {
#if UNITY_EDITOR
            if (IsDone)
            {
                return;
            }

            if (Status == EStatus.None)
            {
                // 检测资源文件是否存在
                string guid = UnityEditor.AssetDatabase.AssetPathToGUID(MainAssetInfo.AssetPath);
                if (string.IsNullOrEmpty(guid))
                {
                    Status    = EStatus.Fail;
                    LastError = $"Not found asset : {MainAssetInfo.AssetPath}";
                    YooLogger.Error(LastError);
                    InvokeCompletion();
                    return;
                }

                Status = EStatus.Loading;

                // 注意:模拟异步加载效果提前返回
                if (IsWaitForAsyncComplete == false)
                {
                    return;
                }
            }

            // 1. 加载资源对象
            if (Status == EStatus.Loading)
            {
                if (MainAssetInfo.AssetType == null)
                {
                    AssetObject = UnityEditor.AssetDatabase.LoadMainAssetAtPath(MainAssetInfo.AssetPath);
                }
                else
                {
                    AssetObject = UnityEditor.AssetDatabase.LoadAssetAtPath(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
                }
                Status = EStatus.Checking;
            }

            // 2. 检测加载结果
            if (Status == EStatus.Checking)
            {
                Status = AssetObject == null ? EStatus.Fail : EStatus.Success;
                if (Status == EStatus.Fail)
                {
                    if (MainAssetInfo.AssetType == null)
                    {
                        LastError = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : null";
                    }
                    else
                    {
                        LastError = $"Failed to load asset object : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType}";
                    }
                    YooLogger.Error(LastError);
                }
                InvokeCompletion();
            }
#endif
        }
Ejemplo n.º 13
0
        /// <summary>
        /// 初始化资源路径映射
        /// </summary>
        public void InitAssetPathMapping(bool locationToLower)
        {
            if (_isInitAssetPathMapping)
            {
                return;
            }
            _isInitAssetPathMapping = true;

            if (EnableAddressable)
            {
                if (locationToLower)
                {
                    YooLogger.Error("Addressable not support location to lower !");
                }

                foreach (var patchAsset in AssetList)
                {
                    string location = patchAsset.Address;
                    if (AssetPathMapping.ContainsKey(location))
                    {
                        throw new Exception($"Address have existed : {location}");
                    }
                    else
                    {
                        AssetPathMapping.Add(location, patchAsset.AssetPath);
                    }
                }
            }
            else
            {
                _locationToLower = locationToLower;
                foreach (var patchAsset in AssetList)
                {
                    string location = patchAsset.AssetPath;
                    if (locationToLower)
                    {
                        location = location.ToLower();
                    }

                    // 添加原生路径的映射
                    if (AssetPathMapping.ContainsKey(location))
                    {
                        throw new Exception($"AssetPath have existed : {location}");
                    }
                    else
                    {
                        AssetPathMapping.Add(location, patchAsset.AssetPath);
                    }

                    // 添加无后缀名路径的映射
                    if (Path.HasExtension(location))
                    {
                        string locationWithoutExtension = StringUtility.RemoveExtension(location);
                        if (AssetPathMapping.ContainsKey(locationWithoutExtension))
                        {
                            YooLogger.Warning($"AssetPath have existed : {locationWithoutExtension}");
                        }
                        else
                        {
                            AssetPathMapping.Add(locationWithoutExtension, patchAsset.AssetPath);
                        }
                    }
                }
            }
        }
Ejemplo n.º 14
0
        public override void Update()
        {
            if (IsDone)
            {
                return;
            }

            if (Status == EStatus.None)
            {
                Status = EStatus.CheckBundle;
            }

            // 1. 检测资源包
            if (Status == EStatus.CheckBundle)
            {
                if (DependBundleGroup.IsDone() == false)
                {
                    return;
                }
                if (OwnerBundle.IsDone() == false)
                {
                    return;
                }

                if (DependBundleGroup.IsSucceed() == false)
                {
                    Status    = EStatus.Fail;
                    LastError = DependBundleGroup.GetLastError();
                    InvokeCompletion();
                    return;
                }

                if (OwnerBundle.Status != AssetBundleLoaderBase.EStatus.Succeed)
                {
                    Status    = EStatus.Fail;
                    LastError = OwnerBundle.LastError;
                    InvokeCompletion();
                    return;
                }

                Status = EStatus.Loading;
            }

            // 2. 加载场景
            if (Status == EStatus.Loading)
            {
                _asyncOp = SceneManager.LoadSceneAsync(_sceneName, SceneMode);
                if (_asyncOp != null)
                {
                    _asyncOp.allowSceneActivation = true;
                    _asyncOp.priority             = _priority;
                    Status = EStatus.Checking;
                }
                else
                {
                    Status    = EStatus.Fail;
                    LastError = $"Failed to load scene : {_sceneName}";
                    YooLogger.Error(LastError);
                    InvokeCompletion();
                }
            }

            // 3. 检测加载结果
            if (Status == EStatus.Checking)
            {
                if (_asyncOp.isDone)
                {
                    SceneObject = SceneManager.GetSceneByName(_sceneName);
                    if (SceneObject.IsValid() && _activateOnLoad)
                    {
                        SceneManager.SetActiveScene(SceneObject);
                    }

                    Status = SceneObject.IsValid() ? EStatus.Success : EStatus.Fail;
                    if (Status == EStatus.Fail)
                    {
                        LastError = $"The load scene is invalid : {MainAssetInfo.AssetPath}";
                        YooLogger.Error(LastError);
                    }
                    InvokeCompletion();
                }
            }
        }
Ejemplo n.º 15
0
        public override void Update()
        {
            if (IsDone)
            {
                return;
            }

            if (Status == EStatus.None)
            {
                Status = EStatus.CheckBundle;
            }

            // 1. 检测资源包
            if (Status == EStatus.CheckBundle)
            {
                if (IsWaitForAsyncComplete)
                {
                    DependBundleGroup.WaitForAsyncComplete();
                    OwnerBundle.WaitForAsyncComplete();
                }

                if (DependBundleGroup.IsDone() == false)
                {
                    return;
                }
                if (OwnerBundle.IsDone() == false)
                {
                    return;
                }

                if (DependBundleGroup.IsSucceed() == false)
                {
                    Status    = EStatus.Fail;
                    LastError = DependBundleGroup.GetLastError();
                    InvokeCompletion();
                    return;
                }

                if (OwnerBundle.Status != AssetBundleLoaderBase.EStatus.Succeed)
                {
                    Status    = EStatus.Fail;
                    LastError = OwnerBundle.LastError;
                    InvokeCompletion();
                    return;
                }

                Status = EStatus.Loading;
            }

            // 2. 加载资源对象
            if (Status == EStatus.Loading)
            {
                if (IsWaitForAsyncComplete)
                {
                    if (MainAssetInfo.AssetType == null)
                    {
                        AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath);
                    }
                    else
                    {
                        AssetObject = OwnerBundle.CacheBundle.LoadAsset(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
                    }
                }
                else
                {
                    if (MainAssetInfo.AssetType == null)
                    {
                        _cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath);
                    }
                    else
                    {
                        _cacheRequest = OwnerBundle.CacheBundle.LoadAssetAsync(MainAssetInfo.AssetPath, MainAssetInfo.AssetType);
                    }
                }
                Status = EStatus.Checking;
            }

            // 3. 检测加载结果
            if (Status == EStatus.Checking)
            {
                if (_cacheRequest != null)
                {
                    if (IsWaitForAsyncComplete)
                    {
                        // 强制挂起主线程(注意:该操作会很耗时)
                        YooLogger.Warning("Suspend the main thread to load unity asset.");
                        AssetObject = _cacheRequest.asset;
                    }
                    else
                    {
                        if (_cacheRequest.isDone == false)
                        {
                            return;
                        }
                        AssetObject = _cacheRequest.asset;
                    }
                }

                Status = AssetObject == null ? EStatus.Fail : EStatus.Success;
                if (Status == EStatus.Fail)
                {
                    if (MainAssetInfo.AssetType == null)
                    {
                        LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : null AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
                    }
                    else
                    {
                        LastError = $"Failed to load asset : {MainAssetInfo.AssetPath} AssetType : {MainAssetInfo.AssetType} AssetBundle : {OwnerBundle.MainBundleInfo.BundleName}";
                    }
                    YooLogger.Error(LastError);
                }
                InvokeCompletion();
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// 轮询更新
        /// </summary>
        public override void Update()
        {
            if (_steps == ESteps.Done)
            {
                return;
            }

            if (_steps == ESteps.None)
            {
                if (MainBundleInfo.IsInvalid)
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = $"The bundle info is invalid : {MainBundleInfo.BundleName}";
                    YooLogger.Error(LastError);
                    return;
                }

                if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromRemote)
                {
                    _steps        = ESteps.Download;
                    _fileLoadPath = MainBundleInfo.GetCacheLoadPath();
                }
                else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromStreaming)
                {
                    _steps        = ESteps.LoadFile;
                    _fileLoadPath = MainBundleInfo.GetStreamingLoadPath();
                }
                else if (MainBundleInfo.LoadMode == BundleInfo.ELoadMode.LoadFromCache)
                {
                    _steps        = ESteps.LoadFile;
                    _fileLoadPath = MainBundleInfo.GetCacheLoadPath();
                }
                else
                {
                    throw new System.NotImplementedException(MainBundleInfo.LoadMode.ToString());
                }
            }

            // 1. 从服务器下载
            if (_steps == ESteps.Download)
            {
                int failedTryAgain = int.MaxValue;
                _downloader = DownloadSystem.BeginDownload(MainBundleInfo, failedTryAgain);
                _steps      = ESteps.CheckDownload;
            }

            // 2. 检测服务器下载结果
            if (_steps == ESteps.CheckDownload)
            {
                if (_downloader.IsDone() == false)
                {
                    return;
                }

                if (_downloader.HasError())
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = _downloader.GetLastError();
                }
                else
                {
                    _steps = ESteps.LoadFile;
                }
            }

            // 3. 加载AssetBundle
            if (_steps == ESteps.LoadFile)
            {
#if UNITY_EDITOR
                // 注意:Unity2017.4编辑器模式下,如果AssetBundle文件不存在会导致编辑器崩溃,这里做了预判。
                if (System.IO.File.Exists(_fileLoadPath) == false)
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = $"Not found assetBundle file : {_fileLoadPath}";
                    YooLogger.Error(LastError);
                    return;
                }
#endif

                // Load assetBundle file
                if (MainBundleInfo.IsEncrypted)
                {
                    if (AssetSystem.DecryptionServices == null)
                    {
                        throw new Exception($"{nameof(AssetBundleFileLoader)} need {nameof(IDecryptionServices)} : {MainBundleInfo.BundleName}");
                    }

                    ulong offset = AssetSystem.DecryptionServices.GetFileOffset();
                    if (_isWaitForAsyncComplete)
                    {
                        CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath, 0, offset);
                    }
                    else
                    {
                        _cacheRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath, 0, offset);
                    }
                }
                else
                {
                    if (_isWaitForAsyncComplete)
                    {
                        CacheBundle = AssetBundle.LoadFromFile(_fileLoadPath);
                    }
                    else
                    {
                        _cacheRequest = AssetBundle.LoadFromFileAsync(_fileLoadPath);
                    }
                }
                _steps = ESteps.CheckFile;
            }

            // 4. 检测AssetBundle加载结果
            if (_steps == ESteps.CheckFile)
            {
                if (_cacheRequest != null)
                {
                    if (_isWaitForAsyncComplete)
                    {
                        // 强制挂起主线程(注意:该操作会很耗时)
                        YooLogger.Warning("Suspend the main thread to load unity bundle.");
                        CacheBundle = _cacheRequest.assetBundle;
                    }
                    else
                    {
                        if (_cacheRequest.isDone == false)
                        {
                            return;
                        }
                        CacheBundle = _cacheRequest.assetBundle;
                    }
                }

                // Check error
                if (CacheBundle == null)
                {
                    _steps    = ESteps.Done;
                    Status    = EStatus.Failed;
                    LastError = $"Failed to load assetBundle : {MainBundleInfo.BundleName}";
                    YooLogger.Error(LastError);
                }
                else
                {
                    _steps = ESteps.Done;
                    Status = EStatus.Succeed;
                }
            }
        }