Example #1
0
        /// <summary>
        /// 异步下载需要更新的资源
        /// </summary>
        /// <param name="ev">下载完成回调函数</param>
        /// <returns></returns>
        IEnumerator AsyncDownloading(ProcessCompleteEvent ev)
        {
            mTotalDownloadBytes   = 0;
            mCurrentDownloadIdx   = 0;
            mAlreadyDownloadBytes = 0;
            foreach (var v in mDownloadingList)
            {
                mTotalDownloadBytes += v.m_FileSize;
            }

            foreach (var v in mDownloadingList)
            {
                string url = mHttpAddress + ResUtils.GetBundleManifestName(Application.platform) + "/" + v.m_Name;
                UnityEngine.Debug.LogFormat("downloading {0} size {1}", v.m_Name, v.m_FileSize);
                WWW www = new WWW(url);
                mWWW = www;
                yield return(www);

                if (www.error == null)
                {
                    string fileName = ResUtils.BundleRootPath + v.m_Name;
                    string dir      = fileName.Substring(0, fileName.LastIndexOf('/'));
                    Directory.CreateDirectory(dir);
                    File.WriteAllBytes(fileName, www.bytes);
                }
                else
                {
                    UnityEngine.Debug.LogErrorFormat("downloading {0} error {1}", v.m_Name, www.error);
                }
                mAlreadyDownloadBytes += v.m_FileSize;
                mCurrentDownloadIdx++;
            }

            //全部下载成功后,再覆盖写入索引文件
            Directory.CreateDirectory(ResUtils.BundleRootPath);
            if (mNewIndexContent != null)
            {
                File.WriteAllText(ResUtils.BundleRootPath + ResUtils.BundleIndexFileName, mNewIndexContent);
                mNewIndexContent = null;
            }

            ev?.Invoke();

            yield return(null);
        }
Example #2
0
        /// <summary>
        /// 从服务器得到资源列表并对比出需要更新的包列表
        /// </summary>
        /// <param name="ev">检查完成后回调函数</param>
        /// <returns></returns>
        IEnumerator AsyncCheckDownloadingList(ProcessCompleteEvent ev)
        {
            //读取本地的idx和apk里的idx文件
            Dictionary <string, BundleItem> localBundlesDict = new Dictionary <string, BundleItem>();
            string localIndexPath = ResUtils.BundleRootPath + ResUtils.BundleIndexFileName;

            if (!File.Exists(localIndexPath)) //如果P目录里没有索引文件,去Resources里拷贝一份到P目录
            {
                UnityEngine.Debug.Log("local idx not found, try copy from default");
                Directory.CreateDirectory(ResUtils.BundleRootPath);
                var txt = Resources.Load(ResUtils.BundleIndexFileName.Substring(ResUtils.BundleIndexFileName.IndexOf('.'))) as TextAsset;
                if (txt != null)
                {
                    File.WriteAllText(ResUtils.BundleRootPath + ResUtils.BundleIndexFileName, txt.text);
                }
            }

            if (File.Exists(localIndexPath))
            {
                string indexContent = File.ReadAllText(localIndexPath);
                if (indexContent != null)
                {
                    IdxFile           file = new IdxFile();
                    List <BundleItem> list = file.Load(indexContent);
                    foreach (var v in list)
                    {
                        localBundlesDict[v.m_Name] = v;
                    }
                }
            }
            else
            {
                UnityEngine.Debug.LogWarning("local idx not found");
            }

            //下载网上的idx文件
            WWW www = new WWW(mHttpAddress + ResUtils.GetBundleManifestName(Application.platform) + "/" + ResUtils.BundleIndexFileName);

            yield return(www);

            if (www.error != null)
            {
                UnityEngine.Debug.Log("remote idx read error " + www.error);
            }

            mDownloadingList.Clear();

            if (www.error == null)
            {
                mNewIndexContent = www.text;
                IdxFile           file       = new IdxFile();
                List <BundleItem> listServer = file.Load(mNewIndexContent);
                foreach (var v in listServer)
                {
                    string     localHash = null;
                    string     netHash   = v.m_HashCode;
                    BundleItem localItem = null;
                    if (localBundlesDict.TryGetValue(v.m_Name, out localItem))
                    {
                        localHash = localItem.m_HashCode;
                    }

                    if (localHash != netHash)
                    {
                        mDownloadingList.Add(v); //网上的资源较新则需要重新下载到本地
                    }
                }

                UnityEngine.Debug.LogFormat("download idx file success! new bundles count {0}, downloading {1}", listServer.Count, mDownloadingList.Count);
            }
            else
            {
                UnityEngine.Debug.LogFormat("download idx file error! {0}", www.error);
            }

            ev?.Invoke();

            yield return(null);
        }
Example #3
0
        /// <summary>
        /// 从AB包里加载资源
        /// </summary>
        /// <param name="assetPath">资源路径,例如 subdir/res1.prefab </param>
        /// <param name="type">资源类型</param>
        /// <returns>加载好的资源对象</returns>
        private UnityEngine.Object LoadAssetFromBundle(string assetPath, Type type)
        {
            //检查依赖关系是否加载,如果没有则加载
            if (mAssetBundleManifest == null)
            {
                AssetBundle manifestBundle = AssetBundle.LoadFromFile(ResUtils.BundleRootPath + ResUtils.GetBundleManifestName(Application.platform));
                if (manifestBundle == null)
                {
                    return(null);
                }

                mAssetBundleManifest = manifestBundle.LoadAsset("AssetBundleManifest", typeof(AssetBundleManifest)) as AssetBundleManifest;
                if (mAssetBundleManifest == null)
                {
                    return(null);
                }
            }

            //获取资源在包内部的名字,这个名字没有路径,但有扩展名,例如 res1.prefab
            string assetName = assetPath.Substring(assetPath.LastIndexOf("/") + 1).ToLower();

            //得到bundle文件的相对路径名,例如 subdir/res1.prefab.unity3d
            string bundleFileName = assetPath + '.' + ResUtils.BundleExtension;

            AssetBundleInfo bundleInfo = null;

            if (mLoadedAssetBundles.TryGetValue(bundleFileName, out bundleInfo))
            {
                bundleInfo.mReferencedCount++;

                if (!bundleInfo.mAssetBundle.isStreamedSceneAssetBundle)
                {
                    UnityEngine.Object obj = bundleInfo.mAssetBundle.LoadAsset(assetName, type);
                    return(obj);
                }
                else
                {
                    return(null); //场景包不需要加载资源,返回即可
                }
            }
            else
            {
                LoadDependencies(bundleFileName);

                bundleInfo = LoadAssetBundleSingle(bundleFileName);

                if (bundleInfo != null && !bundleInfo.mAssetBundle.isStreamedSceneAssetBundle)
                {
                    UnityEngine.Object obj = bundleInfo.mAssetBundle.LoadAsset(assetName, type);
                    return(obj);
                }
                else
                {
                    return(null); //场景包不需要加载资源,返回即可
                }
            }
        }