void InternalUnloadAllAssets(bool unloadUnusedAssets, Action completed)
        {
            Working = true;
            foreach (var kvp in m_LoadedAssets)
            {
                kvp.Value.Release(true);
                AssetRefer.Unspawn(kvp.Value);
            }
            foreach (var kvp in m_LoadedAssetBundles)
            {
                kvp.Value.Release(true);
                AssetBundleRefer.Unspawn(kvp.Value);
            }
            m_LoadedAssets.Clear();
            m_LoadedAssetBundles.Clear();

            if (unloadUnusedAssets)
            {
                Resources.UnloadUnusedAssets();
            }

            if (completed != null)
            {
                completed.Invoke();
            }

            Working = false;
            ActionSequence.Dequeue();
        }
        /// <summary>
        /// Stop all loading tasks, and release all references.(immediately)
        /// </summary>
        public AssetManagementTool Shutdown(bool unloadUnusedAssets = false)
        {
            ActionSequence.Clear();

            if (Working)
            {
                if (m_WorkingCoroutine != null)
                {
                    m_WorkingCoroutine.StopCoroutine();
                }
                Working = false;
            }
            m_WorkingCoroutine = null;

            if (m_LoadingTasks != null)
            {
                m_LoadingTasks.UnspawnLoadingTasks();
                m_LoadingTasks = null;
            }

            while (m_CachedLoadingTasks.Count > 0)
            {
                var list = m_CachedLoadingTasks.Dequeue();
                if (list != null)
                {
                    list.UnspawnLoadingTasks();
                }
            }
            m_CachedLoadingCallbacks.Clear();

            foreach (var kvp in m_LoadedAssets)
            {
                kvp.Value.Release(true);
                AssetRefer.Unspawn(kvp.Value);
            }
            foreach (var kvp in m_LoadedAssetBundles)
            {
                kvp.Value.Release(true);
                AssetBundleRefer.Unspawn(kvp.Value);
            }
            m_LoadedAssets.Clear();
            m_LoadedAssetBundles.Clear();

            if (unloadUnusedAssets)
            {
                Resources.UnloadUnusedAssets();
            }
            return(this);
        }
        public static void UnloadAssets(this List <string> assetPaths, Dictionary <string, AssetRefer> loadedAssets,
                                        Dictionary <string, AssetBundleRefer> loadedAssetBundles, AssetBundleManifest manifest, bool unloadUnusedAssets = false,
                                        Action completed = null)
        {
            var dirty = false;

            for (int i = 0, len = assetPaths.Count; i < len; i++)
            {
                var assetPath = assetPaths[i];

                AssetRefer assetRefer;
                if (loadedAssets.TryGetValue(assetPath, out assetRefer))
                {
                    if (assetRefer.Release() == 0)
                    {
                        // release assetBundle references.

                        loadedAssets.Remove(assetPath);
                        AssetRefer.Unspawn(assetRefer);
                        dirty = true;
                    }
                    else
                    {
                        // not need to release the assetBundle, because the reference count is bigger than zero.
                    }
                }

                var assetBundleNames = manifest.GetAllDependenciesByAssetPath(assetPath, true);

                for (int j = 0, len2 = assetBundleNames.Count; j < len2; j++)
                {
                    var assetBundleName = assetBundleNames[j];
                    AssetBundleRefer assetBundleRefer;
                    if (loadedAssetBundles.TryGetValue(assetBundleName, out assetBundleRefer))
                    {
                        if (assetBundleRefer.Release() == 0)
                        {
                            // release asset references.

                            loadedAssetBundles.Remove(assetBundleName);
                            AssetBundleRefer.Unspawn(assetBundleRefer);
                            dirty = true;
                        }
                        else
                        {
                            // not need to release the asset, because the reference count is bigger than zero.
                        }
                    }
                }
            }

            if (dirty && unloadUnusedAssets)
            {
                Resources.UnloadUnusedAssets();
            }

            if (completed != null)
            {
                completed.Invoke();
            }
        }