Пример #1
0
        private static void RetainBundleInternal(LoadedBundle bundle, int count)
        {
#if UNITY_EDITOR
            if (s_BundleDirectUseCount.ContainsKey(bundle.Name))
            {
                s_BundleDirectUseCount[bundle.Name] += count;
            }
            else
            {
                s_BundleDirectUseCount.Add(bundle.Name, count);
            }
#endif
            for (int i = 0; i < bundle.Dependencies.Count; i++)
            {
                var refBundleName = bundle.Dependencies[i];
                if (!s_BundleRefCounts.ContainsKey(refBundleName))
                {
                    s_BundleRefCounts[refBundleName] = count;
                }
                else
                {
                    s_BundleRefCounts[refBundleName] += count;
                }
            }
        }
Пример #2
0
    // Load bản thân bundle dựa theo tham số là tên
    public static bool LoadBundleInternal(string bundleName)
    {
        LoadedBundle bundle = null;

        // Xem trong từ điển đã có chưa
        loadedBundles.TryGetValue(bundleName, out bundle);
        if (bundle != null)
        {
            // Nếu có rồi thì tăng biến số lượng tham chiếu và trả về true
            bundle.mRefCount++;
            return(true);
        }

        // Nếu vẫn còn đang download cũng tả về true
        if (downloadingWWWs.ContainsKey(bundleName))
        {
            return(true);
        }

        // Nếu chưa có trong từ điển và cũng chưa trong download thì bắt đầu download về hoặc load từ bộ nhớ cache (nếu có)
        WWW download = WWW.LoadFromCacheOrDownload(baseURL + bundleName, manifest.GetAssetBundleHash(bundleName));

        // Sau đó add vào danh sách đang download và trả về false
        downloadingWWWs.Add(bundleName, download);

        return(false);
    }
 private static void AsyncAssetLoaded(AssetBundleRequest request, LoadedBundle loadedBundle)
 {
     if (request.asset != null)
     {
         TrackObjectInternal(request.asset, loadedBundle);
     }
 }
Пример #4
0
    public override bool Update()
    {
        if (m_Request != null)
        {
            return(false);
        }

        LoadedBundle bundle = BundleManager.GetLoadedBundle(m_AssetBundleName, out m_DownloadingError);

        if (bundle != null)
        {
            if (m_IsAdditive)
            {
                m_Request = Application.LoadLevelAdditiveAsync(m_LevelName);
            }
            else
            {
                m_Request = Application.LoadLevelAsync(m_LevelName);
            }
            return(false);
        }
        else
        {
            return(true);
        }
    }
Пример #5
0
 private static void TrackIndepenantInternal(LoadedBundle loadedBundle, GameObject go)
 {
     if (go.scene.name == null)
     {
         throw new System.Exception("GameObject is not instantiated one");
     }
     s_TrackingGameObjects.Add(new TrackingGameObject(go, loadedBundle));
     RetainBundleInternal(loadedBundle, 1);
 }
Пример #6
0
        static void CollectSceneNames(LoadedBundle loadedBundle)
        {
            var scenes = loadedBundle.Bundle.GetAllScenePaths();

            foreach (var scene in scenes)
            {
                s_SceneNames[scene] = loadedBundle;
            }
        }
        private static void AsyncAssetLoaded(AssetBundleRequest request, LoadedBundle loadedBundle)
        {
            if (request.asset != null)
            {
                TrackObjectInternal(request.asset, loadedBundle);
            }

            //because we did increase ref count in loadasync function, it need to be released
            ReleaseBundleInternal(loadedBundle, 1);
        }
        static IEnumerator ReloadBundle(string bundleName, LoadedBundle loadedBundle)
        {
            if (LogMessages)
            {
                Debug.Log($"Start Reloading Bundle {bundleName}");
            }

            var bundleReq = loadedBundle.IsLocalBundle? UnityWebRequestAssetBundle.GetAssetBundle(loadedBundle.LoadPath) :
                            UnityWebRequestAssetBundle.GetAssetBundle(loadedBundle.LoadPath, new CachedAssetBundle(bundleName, loadedBundle.Hash));

            loadedBundle.IsReloading = true;
            yield return(bundleReq.SendWebRequest());

            loadedBundle.IsReloading = false;

            if (bundleReq.isNetworkError || bundleReq.isHttpError)
            {
                Debug.LogError($"Bundle reload error { bundleReq.error }");
                yield break;
            }

            if (!s_AssetBundles.TryGetValue(bundleName, out var currentLoadedBundle) || currentLoadedBundle.Hash != loadedBundle.Hash)
            {
                if (LogMessages)
                {
                    Debug.Log("Bundle To Reload does not exist(changed during loaing)");
                }

                bundleReq.Dispose();
                yield break;
            }

            //if we can swap now
            if (!s_BundleRefCounts.TryGetValue(bundleName, out var refCount) || refCount == 0)
            {
                if (LogMessages)
                {
                    Debug.Log($"Reloaded Bundle {bundleName}");
                }

                loadedBundle.Bundle.Unload(true);
                loadedBundle.Bundle = DownloadHandlerAssetBundle.GetContent(bundleReq);
                bundleReq.Dispose();
            }
            else
            {
                if (LogMessages)
                {
                    Debug.Log($"Reloaded Bundle Cached for later use {bundleName}");
                }

                //store request for laster use
                loadedBundle.RequestForReload = bundleReq;
            }
        }
Пример #9
0
    /// <summary>
    /// 手动从Bundle中加载资源唯一入口
    /// </summary>
    /// <param name="path"></param>
    /// <param name="name"></param>
    /// <param name="type"></param>
    /// <param name="onLoaded"></param>
    /// <param name="async"></param>
    private void LoadAssetFromBundle(string path, string assetName, System.Type type, LoadedCallback onLoaded, bool async, AssetType assetType = AssetType.GameObject)
    {
        if (AppConst.UseAssetBundle)
        {
            Util.Log(string.Format("LoadAssetFromBundle, bundle:{0}, asset:{1}", path, assetName));

            LoadAssetBundle(path, (data) => {
                LoadedBundle abCache = data as LoadedBundle;
                object asset         = null;
                if (abCache != null)
                {
                    string abName = FileHelper.CheckBundleName(path);
                    var cache     = LoadedBundleCtrl.Instance.UnReferenceLoadedBundle(abName);
                    if (cache != null && 0 == cache.ReferencedCount)
                    {
                        cache.ReferencedCount = 1;

                        if (!m_handLoad.Contains(abName))
                        {
                            m_handLoad.Add(abName);
                        }
                    }

                    if (!string.IsNullOrEmpty(assetName))
                    {
                        asset = abCache.LoadAsset(assetName, type);
                        if (type != null && type == typeof(GameObject))
                        {
                            abCache.UnloadSelf();
                        }
                    }
                    else
                    {
                        asset = abCache.Bundle;
                    }
                }

                if (asset == null)
                {
                    Util.LogError(string.Format("LoadAssetFromBundle, path:{0},name:{1}, asset is null", path, assetName));
                }

                if (onLoaded != null)
                {
                    onLoaded(asset);
                }
            }, async);
        }
        else
        {
            LoadAsset(path, onLoaded, type, false, assetType);
        }
    }
Пример #10
0
    /// <summary>
    /// 引用包
    /// </summary>
    /// <param name="abName"></param>
    /// <returns></returns>
    public LoadedBundle ReferenceLoadedBundle(string abName)
    {
        LoadedBundle cache = null;

        m_loadedBundles.TryGetValue(abName, out cache);
        if (cache != null)
        {
            ++cache.ReferencedCount;
        }

        return(cache);
    }
Пример #11
0
    // 加载资源清单
    void LoadManifest(ManifestType mType)
    {
        if (m_manifests.ContainsKey(mType) && m_manifests[mType] != null)
        {
            DestroyImmediate(m_manifests[mType], true);
            m_manifests.Remove(mType);
        }

        string manifestName = mType.ToString();

        Util.Log("LoadManifest manifestName " + manifestName);

        m_manifestNames.Add(manifestName);
        string strFullPath = FileHelper.SearchFilePath(GetManifestType(manifestName).ToString(), manifestName);

        Util.Log("strFullPath: " + strFullPath);

        BundleLoader bLoader = LoaderPool.Instance.GetLoader <BundleLoader>();

        bLoader.Init(strFullPath, manifestName, delegate(object data) {
            LoadedBundle ab = data as LoadedBundle;
            if (ab != null)
            {
                m_manifests[mType]   = ab.LoadAsset <AssetBundleManifest>("AssetBundleManifest");
                m_bundleHeads[mType] = mType.ToString().ToLower().Split('_')[0];

                Util.Log("manifest ab in not null over----");
            }
            else
            {
                Util.LogError("manifest ab is null---------");
            }

            LoadedBundleCtrl.Instance.UnReferenceLoadedBundle(manifestName);  // 不走统一接口是因为manifest文件没有后缀
            LoadedBundleCtrl.Instance.HandRemoveBundle(manifestName);

            if (m_manifests[mType] != null)
            {
                string[] bundles = m_manifests[mType].GetAllAssetBundles();

                for (int i = 0; i < bundles.Length; ++i)
                {
                    if (m_bundleNames.Contains(bundles[i]))
                    {
                        Util.LogError(string.Format("别的清单已同名的包名,{0} {1}", manifestName, bundles[i]));
                    }
                    m_bundleNames.Add(bundles[i]);
                }
            }
        }, false, null, true);
    }
Пример #12
0
 public TrackingObject(Object obj, LoadedBundle loadedBundle)
 {
     if (s_WeakRefPool.Count > 0)
     {
         WeakRef        = s_WeakRefPool.Pop();
         WeakRef.Target = obj;
     }
     else
     {
         WeakRef = new System.WeakReference(obj);
     }
     Bundle   = loadedBundle;
     RefCount = 1;
 }
Пример #13
0
    /// <summary>
    /// 真正从内存卸载包(已判定不是常驻的并且为引用)
    /// </summary>
    /// <param name="abName"></param>
    private void RemoveLoadedBundle(string abName)
    {
        LoadedBundle cache = null;

        m_loadedBundles.TryGetValue(abName, out cache);
        if (cache != null)
        {
            cache.Unload();
            m_loadedBundles.Remove(abName);
        }
        else
        {
            Util.LogWarning(string.Format("移除加载完的包失败,不存在该包:{0}", abName));
        }
    }
Пример #14
0
        private static void TrackObjectInternal(Object obj, LoadedBundle loadedBundle)
        {
            var id = obj.GetInstanceID();

            if (s_TrackingObjects.TryGetValue(id, out var trackingObject))
            {
                trackingObject.RefCount++;
            }
            else
            {
                trackingObject = new TrackingObject(obj, loadedBundle);
                RetainBundleInternal(trackingObject.Bundle, 1);
            }
            s_TrackingObjects[id] = trackingObject; //update
        }
Пример #15
0
    // Get những bundle đã load xong
    public static LoadedBundle GetLoadedBundle(string bundleName, out string error)
    {
        // Nếu xảy ra lỗi trong quá trình download thì trả về null
        if (downloadingErrors.TryGetValue(bundleName, out error))
        {
            return(null);
        }

        // Nếu bundle cần load chưa được tải về thì trả về null
        LoadedBundle bundle = null;

        loadedBundles.TryGetValue(bundleName, out bundle);
        if (bundle == null)
        {
            return(null);
        }


        // Nếu không phụ thuộc vào các bundle khác thì trả về
        string[] dependencies = null;
        if (!mDependencies.TryGetValue(bundleName, out dependencies))
        {
            return(bundle);
        }

        else
        {
            // Với mỗi sự phụ thuộc
            foreach (string dependency in dependencies)
            {
                // Nếu bundle mà phụ thuộc vào có lỗi thì trả về luôn
                if (downloadingErrors.TryGetValue(dependency, out error))
                {
                    return(bundle);
                }

                // Nếu bundle mà phụ thuộc vào chưa được tải xong thì trả về null
                LoadedBundle dependBundle = null;
                loadedBundles.TryGetValue(dependency, out dependBundle);
                if (loadedBundles == null)
                {
                    return(null);
                }
            }
        }

        return(bundle);
    }
Пример #16
0
        private static void ReleaseBundleInternal(LoadedBundle bundle, int count)
        {
#if UNITY_EDITOR
            s_BundleDirectUseCount[bundle.Name] -= count;
#endif
            for (int i = 0; i < bundle.Dependencies.Count; i++)
            {
                var refBundleName = bundle.Dependencies[i];
                if (s_BundleRefCounts.ContainsKey(refBundleName))
                {
                    s_BundleRefCounts[refBundleName] -= count;
                    if (s_BundleRefCounts[refBundleName] <= 0)
                    {
                        ReloadBundle(refBundleName);
                    }
                }
            }
        }
Пример #17
0
    /// <summary>
    /// 记录加载完包
    /// </summary>
    /// <param name="abName"></param>
    /// <param name="bundle"></param>
    /// <param name="refCount"></param>
    /// <returns></returns>
    public LoadedBundle AddLoadedBundle(string abName, AssetBundle bundle, int refCount)
    {
        if (m_loadedBundles.ContainsKey(abName))
        {
            Util.LogWarning(string.Format("已经有同名的资源包加载完了: {0},不应该出现该情况,将被新的覆盖", abName));
        }

        LoadedBundle cache = new LoadedBundle(abName, bundle, refCount);

        m_loadedBundles[abName] = cache;

        if (m_persistentBundles.Contains(abName))
        {
            cache.Persistent = true;
        }

        return(cache);
    }
Пример #18
0
    // Unload bản thân bundle
    public static void UnloadBundleInternal(string bundleName)
    {
        // Nếu bundle không có trong từ điển thì không cần unload
        string       error;
        LoadedBundle bundle = GetLoadedBundle(bundleName, out error);

        if (bundle == null)
        {
            return;
        }

        // Giảm số lượng tham chiếu xuống
        // Nếu = 0 tức là hoàn toàn không cần bundle này nữa nên sẽ unload và xóa khỏi từ điển
        if (--bundle.mRefCount == 0)
        {
            bundle.mBundle.Unload(false);
            loadedBundles.Remove(bundleName);
        }
    }
Пример #19
0
    /// <summary>
    /// 返回不为null 说明 包还没从内存清理(可能未被引用但是清理缓存时间还没到)
    /// </summary>
    /// <param name="abName"></param>
    /// <returns></returns>
    public LoadedBundle UnReferenceLoadedBundle(string abName)
    {
        LoadedBundle cache = null;

        if (!m_loadedBundles.TryGetValue(abName, out cache))
        {
            Util.LogWarning("卸载包失败,不存在该包: " + abName);
            return(null);
        }

        --cache.ReferencedCount;

        if ((AppConst.AssetCacheTime == 0) && cache.IsCanRemove)  //无缓存时间的直接删
        {
            RemoveLoadedBundle(abName);
            return(null);
        }

        return(cache);
    }
Пример #20
0
    public override bool Update()
    {
        if (request != null)
        {
            return(false);
        }

        LoadedBundle bundle = BundleManager.GetLoadedBundle(mBundleName, out mError);

        if (bundle != null)
        {
            request = bundle.mBundle.LoadAssetAsync(mAssetName, mType);
            return(false);
        }

        else
        {
            return(true);
        }
    }
Пример #21
0
    public BundleLoader.BundleState LoadAssetBundle(string path, LoadedCallback onLoaded, bool async = true, BundleLoader parent = null)
    {
        string abName = FileHelper.CheckBundleName(path);

        if (!ManifestHasBundleInfo(abName))
        {
            if (onLoaded != null)
            {
                onLoaded(null);
            }
            return(BundleLoader.BundleState.NotExist);
        }

        LoadedBundle loadedCache = LoadedBundleCtrl.Instance.ReferenceLoadedBundle(abName);

        if (loadedCache != null)
        {
            if (onLoaded != null)
            {
                onLoaded(loadedCache);
            }
            return(BundleLoader.BundleState.Loaded);
        }

        BundleLoader loadingCache = BundleLoaderCtrl.Instance.GetBundleLoader(abName);

        if (loadingCache != null)
        {
            loadingCache.AddHandleCallBack(onLoaded);
            loadingCache.AddParent(parent);
            return(BundleLoader.BundleState.Loading);
        }

        string fullpath = FileHelper.SearchFilePath(GetManifestType(abName).ToString(), abName);           //包最终加载路径

        BundleLoader bLoader = LoaderPool.Instance.GetLoader <BundleLoader>();

        bLoader.Init(fullpath, abName, onLoaded, async, parent);

        return(BundleLoader.BundleState.JustLoad);
    }
Пример #22
0
    /// <summary>
    ///  定时或切换场景时(loading场景)清除无引用的AssetBundle缓存
    /// </summary>
    /// <param name="onlyTimeout"></param>
    public void ClearNoneRefBundle(bool onlyTimeout)
    {
        string[] abNames = new string[m_loadedBundles.Count];
        m_loadedBundles.Keys.CopyTo(abNames, 0);

        string       abName = "";
        LoadedBundle item   = null;

        for (int i = 0; i < abNames.Length; ++i)
        {
            abName = abNames[i];
            item   = m_loadedBundles[abName];
            // 只清除引用计数为0的
            if (item.IsCanRemove && (!onlyTimeout || item.IsTimeOut))  //onlyTimeout:false不用自己缓存时间直接删除
            {
                RemoveLoadedBundle(abName);
            }
        }

        abNames = null;
    }
Пример #23
0
    /// <summary>
    /// 手动移除没被引用的包(等不及定时清理了:场景包等)
    /// </summary>
    /// <param name="abName"></param>
    public void HandRemoveBundle(string abName)
    {
        LoadedBundle cache = null;

        m_loadedBundles.TryGetValue(abName, out cache);
        if (null != cache)
        {
            if (cache.IsCanRemove)
            {
                cache.Unload();
                m_loadedBundles.Remove(abName);
            }
            else
            {
                Util.LogWarning("手动移除包失败,该包还被引用中: " + abName);
            }
        }
        else
        {
            Util.LogWarning("移除加载完的包失败,不存在该包: " + abName);
        }
    }
Пример #24
0
    //**注意代码顺序,不要随便修改流程可引发bug
    void OnLoaded(AssetBundle ab)
    {
        Util.Log("LoadAsset---- " + m_abName);
        if (null == ab)
        {
            Util.LogError("加载包失败 " + m_path);
        }
        Util.Log(string.Format("Load {0} - {1} use {2}ms", m_path, m_async, m_watch.Elapsed.Milliseconds));

        OnLoadCompleted(ab);
        BundleLoaderCtrl.Instance.RemoveBundleLoader(m_abName);

        int refCount = 0;

        if (m_onRefLoaded != null)
        {
            refCount = m_onRefLoaded.GetInvocationList().Length;
        }
        refCount += m_parents.Count;

        LoadedBundle cache = null;

        if (null != ab)
        {
            cache = LoadedBundleCtrl.Instance.AddLoadedBundle(m_abName, ab, refCount);
        }

        if (m_onRefLoaded != null)
        {
            Util.Log("OnLoaded  m_onRefLoaded call---- ");
            m_onRefLoaded(cache);
        }

        for (int i = 0; i < m_parents.Count; i++)
        {
            m_parents[i].ChildLoadEnd(m_abName);
        }
        m_parents.Clear();
    }
Пример #25
0
        private static void TrackObjectsInternal <T>(T[] objs, LoadedBundle loadedBundle) where T : Object
        {
            int retainCount = 0;

            for (int i = 0; i < objs.Length; i++)
            {
                var id = objs[0].GetInstanceID();
                if (s_TrackingObjects.TryGetValue(id, out var trackingObject))
                {
                    trackingObject.RefCount++;
                }
                else
                {
                    trackingObject = new TrackingObject(objs[0], loadedBundle);
                    retainCount++;
                }
                s_TrackingObjects[id] = trackingObject; //update
            }
            if (retainCount > 0)
            {
                RetainBundleInternal(loadedBundle, retainCount);                 //do once
            }
        }
Пример #26
0
        public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseAssetIndexMap objectDatabaseAssetIndexMap, string bundleUrl, bool ignoreDependencies = false)
        {
            BundleDescription bundle;

            using (var packStream = VirtualFileSystem.OpenStream(bundleUrl, VirtualFileMode.Open, VirtualFileAccess.Read))
            {
                bundle = ReadBundleDescription(packStream);
            }

            // Read and resolve dependencies
            if (!ignoreDependencies)
            {
                foreach (var dependency in bundle.Dependencies)
                {
                    await LoadBundle(dependency, objectDatabaseAssetIndexMap);
                }
            }

            lock (loadedBundles)
            {
                LoadedBundle loadedBundle = null;

                foreach (var currentBundle in loadedBundles)
                {
                    if (currentBundle.BundleName == bundleName)
                    {
                        loadedBundle = currentBundle;
                        break;
                    }
                }

                if (loadedBundle == null)
                {
                    loadedBundle = new LoadedBundle
                    {
                        BundleName     = bundleName,
                        BundleUrl      = bundleUrl,
                        Description    = bundle,
                        ReferenceCount = 1
                    };

                    loadedBundles.Add(loadedBundle);
                }
                else
                {
                    loadedBundle.ReferenceCount++;
                }
            }

            // Read objects
            lock (objects)
            {
                foreach (var objectEntry in bundle.Objects)
                {
                    objects[objectEntry.Key] = new ObjectLocation {
                        Info = objectEntry.Value, BundleUrl = bundleUrl
                    };
                }
            }

            // Merge with local (asset bundles) index map
            assetIndexMap.Merge(bundle.Assets);

            // Merge with global object database map
            objectDatabaseAssetIndexMap.Merge(bundle.Assets);
        }
Пример #27
0
        static IEnumerator CoDownloadAssetBundles(AssetbundleBuildManifest manifest, IEnumerable <string> subsetNames, BundleAsyncOperation <bool> result)
        {
            if (!Initialized)
            {
                Debug.LogError("Do Initialize first");
                result.Done(BundleErrorCode.NotInitialized);
                yield break;
            }

#if UNITY_EDITOR
            if (UseAssetDatabase)
            {
                result.Done(BundleErrorCode.Success);
                yield break;
            }
#endif

            var bundlesToUnload    = new HashSet <string>(s_AssetBundles.Keys);
            var downloadBundleList = subsetNames == null ? manifest.BundleInfos : manifest.CollectSubsetBundleInfoes(subsetNames);
            var bundleReplaced     = false; //bundle has been replaced

            result.SetIndexLength(downloadBundleList.Count);

            for (int i = 0; i < downloadBundleList.Count; i++)
            {
                result.SetCurrentIndex(i);
                var bundleInfo = downloadBundleList[i];

                //remove from the set so we can track bundles that should be cleared
                bundlesToUnload.Remove(bundleInfo.BundleName);

                var islocalBundle = s_LocalBundles.TryGetValue(bundleInfo.BundleName, out var localHash) && localHash == bundleInfo.Hash;
                var isCached      = Caching.IsVersionCached(bundleInfo.AsCached);
                result.SetCachedBundle(isCached);

                var loadURL = islocalBundle ? Utility.CombinePath(LocalURL, bundleInfo.BundleName) : Utility.CombinePath(RemoteURL, bundleInfo.BundleName);
                if (LogMessages)
                {
                    Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName}, loadURL {loadURL}, isLocalBundle : {islocalBundle}, isCached {isCached}");
                }
                LoadedBundle previousBundle;

                if (s_AssetBundles.TryGetValue(bundleInfo.BundleName, out previousBundle) && previousBundle.Hash == bundleInfo.Hash)
                {
                    if (LogMessages)
                    {
                        Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName} Complete - load skipped");
                    }
                }
                else
                {
                    var bundleReq = islocalBundle ? UnityWebRequestAssetBundle.GetAssetBundle(loadURL) : UnityWebRequestAssetBundle.GetAssetBundle(loadURL, bundleInfo.AsCached);
                    var operation = bundleReq.SendWebRequest();
                    while (!bundleReq.isDone)
                    {
                        result.SetProgress(operation.progress);
                        yield return(null);
                    }

                    if (bundleReq.isNetworkError || bundleReq.isHttpError)
                    {
                        result.Done(BundleErrorCode.NetworkError);
                        yield break;
                    }

                    if (s_AssetBundles.TryGetValue(bundleInfo.BundleName, out previousBundle))
                    {
                        bundleReplaced = true;
                        previousBundle.Bundle.Unload(false);
                        if (previousBundle.RequestForReload != null)
                        {
                            previousBundle.RequestForReload.Dispose(); //dispose reload bundle
                        }
                        s_AssetBundles.Remove(bundleInfo.BundleName);
                    }

                    var loadedBundle = new LoadedBundle(bundleInfo, loadURL, DownloadHandlerAssetBundle.GetContent(bundleReq), islocalBundle);
                    s_AssetBundles.Add(bundleInfo.BundleName, loadedBundle);
                    CollectSceneNames(loadedBundle);
                    if (LogMessages)
                    {
                        Debug.Log($"Loading Bundle Name : {bundleInfo.BundleName} Complete");
                    }
                    bundleReq.Dispose();
                }
            }

            //let's drop unknown bundles loaded
            foreach (var name in bundlesToUnload)
            {
                var bundleInfo = s_AssetBundles[name];
                bundleInfo.Bundle.Unload(false);
                if (bundleInfo.RequestForReload != null)
                {
                    bundleInfo.RequestForReload.Dispose(); //dispose reload bundle
                }
                s_AssetBundles.Remove(bundleInfo.Name);
            }

            //bump entire bundles' usage timestamp
            //we use manifest directly to find out entire list
            for (int i = 0; i < manifest.BundleInfos.Count; i++)
            {
                var cachedInfo = manifest.BundleInfos[i].AsCached;
                if (Caching.IsVersionCached(cachedInfo))
                {
                    Caching.MarkAsUsed(cachedInfo);
                }
            }

            if (LogMessages)
            {
                Debug.Log($"CacheUsed Before Cleanup : {Caching.defaultCache.spaceOccupied} bytes");
            }
            Caching.ClearCache(600); //as we bumped entire list right before clear, let it be just 600
            if (LogMessages)
            {
                Debug.Log($"CacheUsed After CleanUp : {Caching.defaultCache.spaceOccupied} bytes");
            }

            PlayerPrefs.SetString("CachedManifest", JsonUtility.ToJson(manifest));
            GlobalBundleHash = manifest.GlobalHash.ToString();
            result.Result    = bundleReplaced;
            result.Done(BundleErrorCode.Success);
        }
Пример #28
0
        static IEnumerator CoInitalizeLocalBundles(BundleAsyncOperation result, bool autoReloadBundle)
        {
            if (Initialized)
            {
                result.Done(BundleErrorCode.Success);
                yield break;
            }

            AutoReloadBundle = autoReloadBundle;

            if (LogMessages)
            {
                Debug.Log($"LocalURL : {LocalURL}");
            }

            foreach (var kv in s_AssetBundles)
            {
                kv.Value.Bundle.Unload(false);
            }
            s_SceneNames.Clear();
            s_AssetBundles.Clear();
            s_LocalBundles.Clear();

            var manifestReq = UnityWebRequest.Get(Utility.CombinePath(LocalURL, AssetbundleBuildSettings.ManifestFileName));

            yield return(manifestReq.SendWebRequest());

            if (manifestReq.isHttpError || manifestReq.isNetworkError)
            {
                result.Done(BundleErrorCode.NetworkError);
                yield break;
            }

            if (!AssetbundleBuildManifest.TryParse(manifestReq.downloadHandler.text, out var localManifest))
            {
                result.Done(BundleErrorCode.ManifestParseError);
                yield break;
            }

            //cached version is recent one.
            var cacheIsValid = AssetbundleBuildManifest.TryParse(PlayerPrefs.GetString("CachedManifest", string.Empty), out var cachedManifest) &&
                               cachedManifest.BuildTime > localManifest.BuildTime;

            result.SetIndexLength(localManifest.BundleInfos.Count);
            for (int i = 0; i < localManifest.BundleInfos.Count; i++)
            {
                result.SetCurrentIndex(i);
                result.SetCachedBundle(true);
                AssetbundleBuildManifest.BundleInfo bundleInfoToLoad;
                AssetbundleBuildManifest.BundleInfo cachedBundleInfo = default;
                var localBundleInfo = localManifest.BundleInfos[i];

                bool useLocalBundle =
                    !cacheIsValid ||                                                                      //cache is not valid or...
                    !cachedManifest.TryGetBundleInfo(localBundleInfo.BundleName, out cachedBundleInfo) || //missing bundle or...
                    !Caching.IsVersionCached(cachedBundleInfo.AsCached);                                  //is not cached no unusable.

                bundleInfoToLoad = useLocalBundle ? localBundleInfo : cachedBundleInfo;
                var loadPath = Utility.CombinePath(LocalURL, bundleInfoToLoad.BundleName);

                var bundleReq = UnityWebRequestAssetBundle.GetAssetBundle(loadPath, bundleInfoToLoad.Hash);
                var bundleOp  = bundleReq.SendWebRequest();
                while (!bundleOp.isDone)
                {
                    result.SetProgress(bundleOp.progress);
                    yield return(null);
                }

                if (!bundleReq.isHttpError && !bundleReq.isNetworkError)
                {
                    var loadedBundle = new LoadedBundle(bundleInfoToLoad, loadPath, DownloadHandlerAssetBundle.GetContent(bundleReq), useLocalBundle);
                    s_AssetBundles.Add(localBundleInfo.BundleName, loadedBundle);
                    CollectSceneNames(loadedBundle);

                    if (LogMessages)
                    {
                        Debug.Log($"Local bundle Loaded - Name : {localBundleInfo.BundleName}, Hash : {bundleInfoToLoad.Hash }");
                    }
                }
                else
                {
                    result.Done(BundleErrorCode.NetworkError);
                    yield break;
                }

                bundleReq.Dispose();
                s_LocalBundles.Add(localBundleInfo.BundleName, localBundleInfo.Hash);
            }

            RemoteURL = Utility.CombinePath(localManifest.RemoteURL, localManifest.BuildTarget);
#if UNITY_EDITOR
            if (s_EditorBuildSettings.EmulateWithoutRemoteURL)
            {
                RemoteURL = "file://" + Utility.CombinePath(s_EditorBuildSettings.RemoteOutputPath, UnityEditor.EditorUserBuildSettings.activeBuildTarget.ToString());
            }
#endif
            Initialized = true;
            if (LogMessages)
            {
                Debug.Log($"Initialize Success \nRemote URL : {RemoteURL} \nLocal URL : {LocalURL}");
            }
            result.Done(BundleErrorCode.Success);
        }
Пример #29
0
        public IEnumerator DownloadAndCache(string bundleName, System.Action <AssetBundle> handler, int version)
        {
            LoadedBundle loadedBundle;

            if (_bundles.TryGetValue(bundleName, out loadedBundle))
            {
                if (loadedBundle != null)
                {
                    if (loadedBundle.version == version)
                    {
                        loadedBundle.lastRequest = Time.time;
                        loadedBundle.numRequests++;
                        handler(loadedBundle.bundle);
                        yield break;
                    }
                }
            }

            // Wait for the Caching system to be ready
            while (!Caching.ready)
            {
                yield return(null);
            }

            if (!maintainBundleCache)
            {
#if UNITY_2017_1_OR_NEWER
                Caching.ClearCache();
#else
                Caching.CleanCache();
#endif
            }

            // Load the AssetBundle file from Cache if it exists with the same version or download and store it in the cache
            string bundleUrl = GetBundleUrl(bundleName);
            CoreLogger.LogInfo("BundleManager", string.Format("for bundle {0}, full url is {1}", bundleName, bundleUrl));
            using (WWW www = WWW.LoadFromCacheOrDownload(bundleUrl, version))
            {
                yield return(www);

                if (www.error != null)
                {
                    CoreLogger.LogWarning(name, string.Format("unable to retrieve bundle {0}:{1}", bundleUrl, www.error));
                    handler(null);
                    yield break;
                }

                CoreLogger.LogDebug("BundleManager", string.Format("successfully retrieved bundle {0} from {1}", bundleName, bundleUrl));

                if (loadedBundle != null)
                {
                    CoreLogger.LogDebug("BundleManager", string.Format("New version ({0}) of bundle {1} retrieved - unloading old version ({2}) and caching new one", version, bundleName, loadedBundle.version));
                    loadedBundle.bundle.Unload(false);
                    loadedBundle.bundle = www.assetBundle;
                }
                else
                {
                    CollectGarbage();

                    CoreLogger.LogDebug("BundleManager", string.Format("caching version {0} of bundle {1}", version, bundleName));
                    _bundles[bundleName] = new LoadedBundle()
                    {
                        bundle = www.assetBundle, version = version
                    };
                }

                handler(www.assetBundle);
            }
        }
Пример #30
0
        public async Task LoadBundleFromUrl(string bundleName, ObjectDatabaseContentIndexMap objectDatabaseContentIndexMap, string bundleUrl, bool ignoreDependencies = false)
        {
            List <string> files;
            var           bundle = ReadBundleHeader(bundleUrl, out files);

            if (bundle == null)
            {
                throw new FileNotFoundException("Could not find bundle", bundleUrl);
            }

            // Read and resolve dependencies
            if (!ignoreDependencies)
            {
                foreach (var dependency in bundle.Dependencies)
                {
                    await LoadBundle(dependency, objectDatabaseContentIndexMap);
                }
            }

            LoadedBundle loadedBundle = null;

            lock (loadedBundles)
            {
                foreach (var currentBundle in loadedBundles)
                {
                    if (currentBundle.BundleName == bundleName)
                    {
                        loadedBundle = currentBundle;
                        break;
                    }
                }

                if (loadedBundle == null)
                {
                    loadedBundle = new LoadedBundle
                    {
                        BundleName     = bundleName,
                        BundleUrl      = bundleUrl,
                        Description    = bundle,
                        ReferenceCount = 1,
                        Files          = files,
                        Streams        = new List <Stream>(files.Select(x => (Stream)null)),
                    };

                    loadedBundles.Add(loadedBundle);
                }
                else
                {
                    loadedBundle.ReferenceCount++;
                }
            }

            // Read objects
            lock (objects)
            {
                foreach (var objectEntry in bundle.Objects)
                {
                    objects[objectEntry.Key] = new ObjectLocation {
                        Info = objectEntry.Value, LoadedBundle = loadedBundle
                    };
                }
            }

            // Merge with local (asset bundles) index map
            contentIndexMap.Merge(bundle.Assets);

            // Merge with global object database map
            objectDatabaseContentIndexMap.Merge(bundle.Assets);
        }