public static void BuildAssetBundleEditor() { AssetBundle.UnloadAllAssetBundles(true); SetBundleNameAll(); string dir = Helper.CheckPathExistence(PathDefine.StreamingAssetsPathByPF("Editor") + "AssetsBundle/"); if (Directory.Exists(dir) == false) { Directory.CreateDirectory(dir); } BuildAssetBundleOptions options = BuildAssetBundleOptions.DeterministicAssetBundle; AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(dir, options, BuildTarget.StandaloneWindows64); string[] allAssetBundlesName = manifest.GetAllAssetBundles(); JsonData allJsonData = new JsonData() { }; allJsonData["VersionCode"] = GameSetting.Instance.versionCode; allJsonData["ABHashList"] = new JsonData(); for (int i = 0; i < allAssetBundlesName.Length; i++) { Hash128 hash = manifest.GetAssetBundleHash(allAssetBundlesName[i]); int hashCode = hash.GetHashCode(); JsonData curABData = new JsonData(); curABData[allAssetBundlesName[i]] = hashCode; allJsonData["ABHashList"].Add(curABData); } //总AssetBundle数据 手动加上 JsonData assetBundleABData = new JsonData(); assetBundleABData["AssetsBundle"] = manifest.GetHashCode(); allJsonData["ABHashList"].Add(assetBundleABData); string json = Helper.JsonTree(allJsonData.ToJson()); byte[] byteArray = System.Text.Encoding.Default.GetBytes(json.ToString()); //存一份version string jsonSavePathLocal = PathDefine.StreamingAssetsPath("Editor") + "Version/version.json"; FileInfo fileInfoLocal = new FileInfo(jsonSavePathLocal); Helper.SaveAssetToLocalFile(Helper.CheckPathExistence(fileInfoLocal.Directory.FullName), fileInfoLocal.Name, byteArray); AssetDatabase.Refresh(); }
/// <summary> /// 获取需要更新的文件 /// </summary> /// <returns></returns> private List <string> GetUpdateFileName() { if (oldManifest == null) { if (newManifest != null) { return(new List <string>(newManifest.GetAllAssetBundles())); } else { return(new List <string>()); } } List <string> updateFileNames = new List <string>(); int newHashCode = newManifest.GetHashCode(); int oldHashCode = oldManifest.GetHashCode(); if (newHashCode == oldHashCode) { updateFileNames = new List <string>(); } else { string[] newAssets = newManifest.GetAllAssetBundles(); string[] oldAssets = oldManifest.GetAllAssetBundles(); Dictionary <string, Hash128> oldHashs = new Dictionary <string, Hash128>(); foreach (string name in oldAssets) { oldHashs.Add(name, oldManifest.GetAssetBundleHash(name)); } foreach (string name in newAssets) { if (oldHashs.ContainsKey(name)) { Hash128 newHash = newManifest.GetAssetBundleHash(name); if (newHash != oldHashs[name]) { updateFileNames.Add(name); } } else { updateFileNames.Add(name); } } } return(updateFileNames); }
//获取需要下载的文件列表 private List <string> getDownloadFileName() { if (curManifest == null) { if (onlineManifest == null) { return(new List <string>()); } else { return(new List <string>(onlineManifest.GetAllAssetBundles())); } } List <string> tempList = new List <string>(); var curHashCode = curManifest.GetHashCode(); var onlineHashCode = onlineManifest.GetHashCode(); if (curHashCode != onlineHashCode) { // 比对筛选 var curABList = curManifest.GetAllAssetBundles(); var onlineABList = onlineManifest.GetAllAssetBundles(); Dictionary <string, Hash128> curABHashDic = new Dictionary <string, Hash128>(); foreach (var iter in curABList) { curABHashDic.Add(iter, curManifest.GetAssetBundleHash(iter)); } foreach (var iter in onlineABList) { if (curABHashDic.ContainsKey(iter)) //本地有该文件 但与服务器不同 { Hash128 onlineHash = onlineManifest.GetAssetBundleHash(iter); if (onlineHash != curABHashDic[iter]) { tempList.Add(iter); } } else { tempList.Add(iter); } } } return(tempList); }
/// <summary> /// 拿到所有ab的hash /// </summary> /// <returns></returns> public static List <AssetBundleHashInfo> GetAllAssetbundleHashList() { AssetBundle assetBundle = AssetBundle.LoadFromFile(AssetBundleLoad.GetAbPath() + AssetBundleLoad.FolderName); AssetBundleManifest manifest = assetBundle.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); List <AssetBundleHashInfo> assetbundleHashInfoList = new List <AssetBundleHashInfo>(); string[] allAssetbundleNames = manifest.GetAllAssetBundles(); for (int i = 0; i < allAssetbundleNames.Length; i++) { string abName = allAssetbundleNames[i]; AssetBundleHashInfo info = new AssetBundleHashInfo(); info.abName = abName; info.hash = manifest.GetAssetBundleHash(abName).ToString(); assetbundleHashInfoList.Add(info); } //Manifest别忘了加 AssetBundleHashInfo info2 = new AssetBundleHashInfo(); info2.abName = AssetBundleLoad.FolderName; info2.hash = manifest.GetHashCode().ToString(); assetbundleHashInfoList.Add(info2); assetBundle.Unload(true); return(assetbundleHashInfoList); }
/// <summary> /// 上传AB 上传的时候需要生成AB版本文件 /// </summary> private void Upload() { //区分平台 string pfStr = string.Empty; if (platform == 0) { pfStr = "Editor"; } else if (platform == 1) { pfStr = "Android"; } else if (platform == 2) { pfStr = "Ios"; } Debug.Log("正在上传" + pfStr + "平台的AssetsBundle"); #region 处理AllPackageVersion.json文件 JsonData allPackageVersionData = new JsonData() { }; string allPackageVersionDataPath = PathDefine.serverPathInLocal_AllPackageVersion(pfStr); string pristinePkgVersionText = string.Empty; //新版本信息 JsonData curPackageVersionData = new JsonData(); curPackageVersionData["Version"] = version; curPackageVersionData["isNewPackage"] = isNewPackage; //检查版本文件(记录isnewpackage)路径是否有文件 if (File.Exists(allPackageVersionDataPath)) { //有就直接加载 pristinePkgVersionText = File.ReadAllText(allPackageVersionDataPath, System.Text.Encoding.UTF8); JsonData jsonData = JsonMapper.ToObject(pristinePkgVersionText); for (int i = 0; i < jsonData.Count; i++) { allPackageVersionData.Add(jsonData[i]); } //检查当前版本是否已经在文件内 bool versionIsInFile = false; for (int i = 0; i < allPackageVersionData.Count; i++) { if (int.Parse(allPackageVersionData[i]["Version"].ToString()) == version) { allPackageVersionData[i]["isNewPackage"] = isNewPackage; versionIsInFile = true; break; } } if (!versionIsInFile) { allPackageVersionData.Add(curPackageVersionData); } } else { allPackageVersionData.Add(curPackageVersionData); } //将pkgJson数据转化成byte[] string pkgJson = Helper.JsonTree(allPackageVersionData.ToJson()); byte[] pkgJsonByteArray = System.Text.Encoding.Default.GetBytes(pkgJson.ToString()); FileInfo pkgFileInfo = new FileInfo(allPackageVersionDataPath); Helper.SaveAssetToLocalFile(Helper.CheckPathExistence(pkgFileInfo.Directory.FullName), pkgFileInfo.Name, pkgJsonByteArray); #endregion #region 移动有变动的AB到指定文件夹 //先把对应版本文件夹删掉 if (Directory.Exists(PathDefine.serverPathInLocal(pfStr, version))) { Helper.DeleteFiles(PathDefine.serverPathInLocal(pfStr, version)); } //获取最后的版本,然后去对应文件夹查找相应的AssetBundle文件 int serverRecentVersion = 0; if (isNewPackage) { serverRecentVersion = version; } else { if (allPackageVersionData.Count == 1) { //误操作提示 Debug.LogError("上传热更版本前需要有一个整包版本,当前已退出上传AB流程,请检查版本"); return; } serverRecentVersion = int.Parse(allPackageVersionData[allPackageVersionData.Count - 2]["Version"].ToString()); } List <string> shouldMoveList = new List <string>(); AssetBundle localAssetBundle = AssetBundle.LoadFromFile(PathDefine.StreamingAssetsPath(pfStr) + "AssetsBundle/AssetsBundle"); AssetBundleManifest localABManifest = localAssetBundle.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); localAssetBundle.Unload(false); AssetBundle serverAssetBundle = null; AssetBundleManifest serverABManifest = null; if (!isNewPackage) { serverAssetBundle = AssetBundle.LoadFromFile(PathDefine.serverPathInLocal(pfStr, serverRecentVersion) + "AssetsBundle"); serverABManifest = serverAssetBundle.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); serverAssetBundle.Unload(false); } string[] localAllABName = localABManifest.GetAllAssetBundles(); for (int i = 0; i < localAllABName.Length; i++) { Hash128 localHash = localABManifest.GetAssetBundleHash(localAllABName[i]); Hash128 serverHash = new Hash128(); if (serverABManifest != null) { serverHash = serverABManifest.GetAssetBundleHash(localAllABName[i]); } if (serverABManifest == null)//说明是新包,全部增加 { shouldMoveList.Add(localAllABName[i]); } else if (localHash.GetHashCode() != serverHash.GetHashCode())//说明是改动过的 { shouldMoveList.Add(localAllABName[i]); } } //上面的localABManifest.GetAllAssetBundles()没有包含这个文件,补上 //这个文件每次都会被改动到 shouldMoveList.Add("AssetsBundle"); //移动AB包 for (int i = 0; i < shouldMoveList.Count; i++) { string targetPath = PathDefine.serverPathInLocal(pfStr, version) + shouldMoveList[i]; string[] targetPathGroup = targetPath.Split('/'); string needCheckDirectoryPath = string.Empty;//需要检查的文件夹地址 for (int j = 0; j < targetPathGroup.Length - 1; j++) { needCheckDirectoryPath = needCheckDirectoryPath + (j == 0 ? string.Empty : "/") + targetPathGroup[j]; } Helper.CheckPathExistence(needCheckDirectoryPath); byte[] fileByte = File.ReadAllBytes(PathDefine.StreamingAssetsPath(pfStr) + "AssetsBundle/" + shouldMoveList[i]); FileStream fsDes = File.Create(targetPath); fsDes.Write(fileByte, 0, fileByte.Length); fsDes.Flush(); fsDes.Close(); } #endregion #region 创建fileversion.json文件 JsonData newFileInfoJsonData = new JsonData() { }; //判断是否全新整包 if (isNewPackage) { for (int i = 0; i < shouldMoveList.Count; i++) { //拼接AB版本文件,用于记录每个AB的版本 byte[] b = File.ReadAllBytes(PathDefine.StreamingAssetsPath(pfStr) + "AssetsBundle/" + shouldMoveList[i]); JsonData jd = CreteFileVersionItemJson(shouldMoveList[i], version, b.Length); newFileInfoJsonData.Add(jd); } } else { string recentFileInfoText = File.ReadAllText(PathDefine.serverPathInLocal(pfStr, serverRecentVersion) + "fileversion.json", System.Text.Encoding.UTF8); newFileInfoJsonData = JsonMapper.ToObject(recentFileInfoText); //检查替换 for (int i = 0; i < newFileInfoJsonData.Count; i++) { for (int j = 0; j < shouldMoveList.Count; j++) { if (shouldMoveList[j] == newFileInfoJsonData[i]["name"].ToString()) { //下面需要补充info byte[] b = File.ReadAllBytes(PathDefine.StreamingAssetsPath(pfStr) + "AssetsBundle/" + shouldMoveList[j]); newFileInfoJsonData[i]["info"][0]["version"] = version; newFileInfoJsonData[i]["info"][0]["size"] = b.Length; break; } } } //检查新增 for (int i = 0; i < shouldMoveList.Count; i++) { bool isAdd = true; for (int j = 0; j < newFileInfoJsonData.Count; j++) { //检查新增的文件名是否在fileversion文件内 if (shouldMoveList[i] == newFileInfoJsonData[j]["name"].ToString()) { isAdd = false; break; } } if (isAdd) { byte[] b = File.ReadAllBytes(PathDefine.StreamingAssetsPath(pfStr) + "AssetsBundle/" + shouldMoveList[i]); JsonData jd = CreteFileVersionItemJson(shouldMoveList[i], version, b.Length); newFileInfoJsonData.Add(jd); } } } string verJson = Helper.JsonTree(newFileInfoJsonData.ToJson()); byte[] byteArray = System.Text.Encoding.Default.GetBytes(verJson.ToString()); //保存版本文件 string saveFileVersionPath = PathDefine.serverPathInLocal(pfStr, version) + "fileversion.json"; if (File.Exists(saveFileVersionPath)) { File.Delete(saveFileVersionPath); AssetDatabase.Refresh(); } FileInfo verFileInfo = new FileInfo(saveFileVersionPath); Helper.SaveAssetToLocalFile(Helper.CheckPathExistence(verFileInfo.Directory.FullName), verFileInfo.Name, byteArray); #endregion #region 创建version.json文件 用于对比HASH 下载 JsonData versionJsonData = new JsonData() { }; versionJsonData["VersionCode"] = version; versionJsonData["ABHashList"] = new JsonData(); for (int i = 0; i < localAllABName.Length; i++) { Hash128 localHash = localABManifest.GetAssetBundleHash(localAllABName[i]); JsonData curABData = new JsonData(); curABData[localAllABName[i]] = localHash.GetHashCode(); versionJsonData["ABHashList"].Add(curABData); } //添加当前总AB文件的HASH对比 JsonData assetsBundleJD = new JsonData(); assetsBundleJD["AssetsBundle"] = localABManifest.GetHashCode(); versionJsonData["ABHashList"].Add(assetsBundleJD); string json = Helper.JsonTree(versionJsonData.ToJson()); byte[] versionJsonByteArray = System.Text.Encoding.Default.GetBytes(json.ToString()); //存一份version string jsonSavePathLocal = PathDefine.serverPathInLocal(pfStr, version) + "version.json"; FileInfo fileInfoLocal = new FileInfo(jsonSavePathLocal); Helper.SaveAssetToLocalFile(Helper.CheckPathExistence(fileInfoLocal.Directory.FullName), fileInfoLocal.Name, versionJsonByteArray); #endregion Debug.Log("上传完毕"); }
/// <summary> /// //从服务器下载到本地 /// </summary> /// <param name="AssetsHost">服务器路径</param> /// <param name="RootAssetsName">总依赖文件目录路径</param> /// <param name="AssetName">请求资源名称</param> /// <param name="saveLocalPath">保存到本地路径,一般存在Application.persistentDataPath</param> /// <returns></returns> IEnumerator DownLoadAssetsWithDependencies2Local(string AssetsHost, string RootAssetsName, string AssetName, string saveLocalPath, dlg_OnAssetBundleDownLoadOver OnDownloadOver = null) { WWW ServerManifestWWW = null; //用于存储依赖关系的 AssetBundle AssetBundle LocalManifestAssetBundle = null; //用于存储依赖关系的 AssetBundle AssetBundleManifest assetBundleManifestServer = null; //服务器 总的依赖关系 AssetBundleManifest assetBundleManifestLocal = null; //本地 总的依赖关系 if (RootAssetsName != "") //总依赖项为空的时候去加载总依赖项 { ServerManifestWWW = new WWW(AssetsHost + "/" + RootAssetsName); Debug.Log("___当前请求总依赖文件~\n"); yield return(ServerManifestWWW); if (ServerManifestWWW.isDone) { //加载总的配置文件 assetBundleManifestServer = ServerManifestWWW.assetBundle.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); Debug.Log("___当前请求总依赖文件~\n"); } else { throw new Exception("总依赖文件下载失败~~~\n"); } } //获取需要加载物体的所有依赖项 string[] AllDependencies = new string[0]; if (assetBundleManifestServer != null) { //根据名称获取依赖项 AllDependencies = assetBundleManifestServer.GetAllDependencies(AssetName); } //下载队列 并获取每个资源的Hash值 Dictionary <string, Hash128> dicDownloadInfos = new Dictionary <string, Hash128>(); for (int i = AllDependencies.Length - 1; i >= 0; i--) { dicDownloadInfos.Add(AllDependencies[i], assetBundleManifestServer.GetAssetBundleHash(AllDependencies[i])); } dicDownloadInfos.Add(AssetName, assetBundleManifestServer.GetAssetBundleHash(AssetName)); if (assetBundleManifestServer != null) //依赖文件不为空的话下载依赖文件 { Debug.Log("Hash:" + assetBundleManifestServer.GetHashCode()); dicDownloadInfos.Add(RootAssetsName, new Hash128(0, 0, 0, 0)); } //卸载掉,无法同时加载多个配置文件 ServerManifestWWW.assetBundle.Unload(true); if (File.Exists(saveLocalPath + "/" + RootAssetsName)) { LocalManifestAssetBundle = AssetBundle.LoadFromFile(saveLocalPath + "/" + RootAssetsName); assetBundleManifestLocal = LocalManifestAssetBundle.LoadAsset <AssetBundleManifest>("AssetBundleManifest"); } foreach (var item in dicDownloadInfos) { if (!CheckLocalFileNeedUpdate(item.Key, item.Value, RootAssetsName, saveLocalPath, assetBundleManifestLocal)) { Debug.Log("无需下载:" + item.Key); continue; } else { DeleteFile(saveLocalPath + "/" + item.Key); } //直接加载所有的依赖项就好了 WWW wwwAsset = new WWW(AssetsHost + "/" + item.Key); //获取加载进度 while (!wwwAsset.isDone) { Debug.Log(string.Format("下载 {0} : {1:N1}%", item.Key, (wwwAsset.progress * 100))); yield return(new WaitForSeconds(0.2f)); } //保存到本地 SaveAsset2LocalFile(saveLocalPath, item.Key, wwwAsset.bytes, wwwAsset.bytes.Length); } if (LocalManifestAssetBundle != null) { LocalManifestAssetBundle.Unload(true); } if (OnDownloadOver != null) { OnDownloadOver(); } }