public static void GenAssetsMD5() { XmlDocument xmldoc = new XmlDocument(); XmlDeclaration xmldecl = xmldoc.CreateXmlDeclaration("1.0", "UTF-8", "yes"); xmldoc.AppendChild(xmldecl); //加入一个根元素 XmlElement xmlRootElem = xmldoc.CreateElement("", "AssetsMD5", ""); xmldoc.AppendChild(xmlRootElem); List <string> fileList = PackUtils.GetFilesFormFolder("/StreamingAssets/", "*.*", true); for (int i = 0; i < fileList.Count; i++) { string filePath = fileList[i].Replace("Assets/StreamingAssets/", ""); string fileMD5 = ResUtils.GetFileMD5(Application.dataPath + "/StreamingAssets/" + filePath); XmlNode root = xmldoc.SelectSingleNode("AssetsMD5"); XmlElement xe1 = xmldoc.CreateElement("File"); xe1.SetAttribute("path", filePath); xe1.SetAttribute("md5", fileMD5); root.AppendChild(xe1); } //保存创建好的XML文档 string xmlFilePath = Application.dataPath + "/Resources/AssetsMD5.xml"; xmldoc.Save(xmlFilePath); }
/// <summary> /// 遍历目录下的资源文件,生成索引文件 /// </summary> /// <param name="resDir">要遍历的目录</param> private static void GenerateIndexFile(string resDir) { string platName = resDir; if (platName[platName.Length - 1] == '/') { platName = platName.Substring(0, platName.Length - 1); } platName = platName.Substring(platName.LastIndexOf('/') + 1); DirectoryInfo dirInfo = new DirectoryInfo(resDir); var files = dirInfo.GetFiles("*", SearchOption.AllDirectories); List <BundleItem> items = new List <BundleItem>(); foreach (var file in files) { if (file.Extension != ResUtils.BundleExtension && file.Name != platName) { continue; //只处理资源关系文件和特定后缀的文件 } BundleItem item = new BundleItem(); item.m_HashCode = ResUtils.GetFileHash(file.FullName); item.m_FileSize = ResUtils.GetFileSize(file.FullName); item.m_Name = file.FullName.Substring(resDir.Length); items.Add(item); } IdxFile idx = new IdxFile(); string idxContent = IdxFile.SaveString(items, resDir); string filePath = resDir + ResUtils.BundleIndexFileName; File.WriteAllText(filePath, idxContent); Debug.Log("=========Generated index file to .." + filePath); }
private void LoadColors() { foreach (var color in ResUtils.LoadColors()) { Panel colorPanel = new Panel(); colorPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; colorPanel.BackColor = ColorTranslator.FromHtml(color); colorPanel.Size = new Size(30, 30); colorPanel.Click += new System.EventHandler((s, args) => { BackgroundTextBox.Text = ColorTranslator.ToHtml((s as Panel).BackColor); }); ColorsFlowLayout.Controls.Add(colorPanel); } }
/// <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; } if (ev != null) { ev.Invoke(); } yield return(null); }
/* 函数说明: 开始一个下载请求 */ public IEnumerator StartRequest(string fileName) { m_fileName = fileName; // 判断文件是否已存在 if (GetDownloadedFile(m_fileName, out m_filePath)) { m_status = Status.Finish; Close(); yield break; } // 创建本地下载目录 if (!ResUtils.MakeDirectory(m_filePath)) { m_status = Status.Failed; Close(); Debug.LogError(string.Format("HttpDownloader : MakeDirectory '{0}' Error !", m_filePath)); yield break; } string url = ResUpdater.Instance().GetDownloadUrl(m_fileName); if (string.IsNullOrEmpty(url)) { m_status = Status.Failed; Close(); Debug.LogError("HttpDownloader : download url is null !"); yield break; } m_status = Status.Downing; m_www = new WWW(url); yield return(m_www); // 如果错误, 则返回 if (!string.IsNullOrEmpty(m_www.error)) { m_status = Status.Failed; yield break; } // 写文件 WriteFile(m_filePath, m_www.bytes); }
public static bool GetDownloadedFile(string fileName, out string fullPath) { Debug.LogError("Start GetDownloadedFile " + fileName); if (string.IsNullOrEmpty(fileName)) { Debug.LogError("if (string.IsNullOrEmpty(fileName))"); fullPath = ""; return(false); } fullPath = ResUtils.GetDownloadPath(fileName); if (!File.Exists(fullPath)) { Debug.LogError("if (!File.Exists(fullPath)) fullPath :" + fullPath); return(false); } // 匹配文件md5 Dictionary <string, string> serverFilesMD5 = ResUpdater.Instance().serverFilesMD5; string fileMD5; if (serverFilesMD5.TryGetValue(fileName, out fileMD5)) { Debug.LogError("if (serverFilesMD5.TryGetValue(fileName, out fileMD5)) fileMD5 " + fileMD5); if (string.IsNullOrEmpty(fileMD5)) { return(false); } string localFileMD5 = ResUtils.GetFileMD5(fullPath); Debug.LogError(" if (string.IsNullOrEmpty(fileMD5)) fileMD5 " + fileMD5 + " localFileMD5 " + localFileMD5); return(string.Compare(fileMD5, localFileMD5, true) == 0); } Debug.LogError("Stop GetDownloadedFile"); return(false); }
/// <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); //场景包不需要加载资源,返回即可 } } }
/// <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); } if (ev != null) { ev.Invoke(); } yield return(null); }
static void OpenBuildTargetFileWindow() { ResUtils.InitResInfo(Application.dataPath + "/Resources", true); EditorWindow.GetWindow <BuildTargetFileWindow>(); }