/// <summary> /// 构建基于SQLite的bundlemap /// </summary> /// <param name="buildTarget"></param> /// <param name="builtAssetBundleManifest"></param> /// <param name="bundleIndexMapPath"></param> /// <param name="fileNameCaseSensitive"></param> public static bool DoSqliteBundleIndexMap(string bundleIndexMapPath, BuildTarget buildTarget, AssetBundleManifest builtAssetBundleManifest = null, bool fileNameCaseSensitive = true) { try { FileUtil.ClearOrCreateEmptyFolder(bundleIndexMapPath); string assetsBuildPath = GOEPackUIHelperV5.GetBundleOutputPath(buildTarget); if (!builtAssetBundleManifest) { string buildManifestBundlePath = Path.Combine(assetsBuildPath, PathConfig.BUILD_MANIFEST_BUNDLE); //manifest实际上在AssetBundle里,.manifest是给外面看的(只有build出来的manifest有信息,别的都没有) AssetBundle buildManifestBundle = AssetBundle.LoadFromFile(buildManifestBundlePath); builtAssetBundleManifest = buildManifestBundle.LoadAsset <AssetBundleManifest>("assetbundlemanifest"); buildManifestBundle.Unload(false); } string currentBuildBundleMapDbPath = Path.Combine(assetsBuildPath, PathConfig.SQLITE_BUNDLE_MAP_NAME); BundleIndicesMap bundleIndexMap = new BundleIndicesMap(currentBuildBundleMapDbPath); bundleIndexMap.ClearBundleIndicesData(); string[] allAssetBundleNames = builtAssetBundleManifest.GetAllAssetBundles(); for (int i = 0; i < allAssetBundleNames.Length; ++i) { string originBundlePath = Path.Combine(assetsBuildPath, allAssetBundleNames[i]); AssetBundle buildBundle = AssetBundle.LoadFromFile(originBundlePath); if (buildBundle == null) { throw new Exception($"no bundle:{Path.Combine(assetsBuildPath, allAssetBundleNames[i])}"); } string bundleHash = builtAssetBundleManifest.GetAssetBundleHash(allAssetBundleNames[i]).ToString(); string[] bundleIncludeAssets = buildBundle.GetAllAssetNames(); string[] bundleIncludeScenes = buildBundle.GetAllScenePaths(); buildBundle.Unload(true); int bundleFileSize = (int)FileUtil.GetFileLength(Path.Combine(assetsBuildPath, allAssetBundleNames[i])); string[] bundleAssets = new string[bundleIncludeAssets.Length + bundleIncludeScenes.Length]; int assetIndex = 0; for (int j = 0; j < bundleIncludeAssets.Length; ++j) { bundleAssets[assetIndex++] = fileNameCaseSensitive ? Path.GetFileName(FileUtil.GetFileRealNameByFuzzyCaseInsensitivePath(bundleIncludeAssets[j])) : Path.GetFileName(bundleIncludeAssets[j]); } for (int j = 0; j < bundleIncludeScenes.Length; ++j) { bundleAssets[assetIndex++] = fileNameCaseSensitive ? Path.GetFileName(FileUtil.GetFileRealNameByFuzzyCaseInsensitivePath(bundleIncludeScenes[j])) : Path.GetFileName(bundleIncludeScenes[j]); } string[] bundleDependencies = builtAssetBundleManifest.GetAllDependencies(allAssetBundleNames[i]); for (int j = 0; j < bundleDependencies.Length; ++j) { string dependencyFullPath = Path.Combine(assetsBuildPath, bundleDependencies[j]); dependencyFullPath = fileNameCaseSensitive ? FileUtil.GetFileRealNameByFuzzyCaseInsensitivePath(dependencyFullPath) : dependencyFullPath; bundleDependencies[j] = Path.GetFileName(dependencyFullPath); } bundleIndexMap.AddBundleIndicesByTransaction(allAssetBundleNames[i], bundleHash, bundleDependencies, bundleAssets, bundleFileSize); //AssetBundle HashName string bundleHashName = Path.Combine(bundleIndexMapPath, $"{bundleHash}{PathConfig.BUNDLE_POSTFIX}"); File.Copy(originBundlePath, bundleHashName); } AssetBundle.UnloadAllAssetBundles(true); bundleIndexMap.ForceCommit(); string bundleMapDbDstPath = Path.Combine(bundleIndexMapPath, PathConfig.SQLITE_BUNDLE_MAP_NAME); File.Copy(currentBuildBundleMapDbPath, bundleMapDbDstPath); using (FileStream fs = new FileStream(bundleMapDbDstPath, FileMode.Open)) { System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create(); byte[] bundleMapHash = sha.ComputeHash(fs); string bundlemapHashFilePath = Path.Combine(bundleIndexMapPath, PathConfig.SQLITE_BUNDLE_MAP_HASH); using (FileStream fs2 = new FileStream(bundlemapHashFilePath, FileMode.CreateNew)) fs2.Write(bundleMapHash, 0, bundleMapHash.Length); bundleIndexMap.SetBundleMapInfo(BundleIndicesMap.BundleMapKey.BUNDLEMAP_IDENTIFY, Encoding.UTF8.GetString(bundleMapHash)); bundleIndexMap.Dispose(); } //Copy To StreamingAssets if (Directory.Exists(PathConfig.CODE_STREAMINGASSET_PATH)) { File.Copy(currentBuildBundleMapDbPath, Path.Combine(PathConfig.CODE_STREAMINGASSET_PATH, PathConfig.SQLITE_BUNDLE_MAP_NAME), true); } //只有Windows的Bundle需要拷贝 //if (buildTarget == BuildTarget.StandaloneWindows64 || buildTarget == BuildTarget.StandaloneWindows || buildTarget == BuildTarget.StandaloneOSX) // CopyGOEBundleToPath(bundleIndexMapPath); //else //{ //Copy RawAssets string rawAssetDirPath = Path.Combine(assetsBuildPath, PathConfig.RAW_ASSET_PATH); DirectoryInfo rawAssetDir = new DirectoryInfo(rawAssetDirPath); if (rawAssetDir.Exists) { FileInfo[] rawAssetFileInfoList = rawAssetDir.GetFiles(); foreach (FileInfo rawAssetFile in rawAssetFileInfoList) { string dstPath = Path.Combine(bundleIndexMapPath, rawAssetFile.Name); rawAssetFile.CopyTo(dstPath); } } //} return(true); } catch (Exception ex) { throw ex; } }
static void PackAllResourcesV5(BuildTarget target, bool isReleaseBuild = false, HashSet <string> exc = null) { isForRelease = isReleaseBuild; //清空GENERATE目录 ClearGenerate(); //拷贝外部公共文件 PreparePackFiles(target); AssetDatabase.Refresh(); Dictionary <string, object> extra; string error; try { //todo:后期继续重构 AssetBundleManifest buildManifest; if (!GOEPackUIHelperV5.PackAll(true, target, out error, exc, out extra, out buildManifest) || buildManifest == null) { Debug.LogError("Pack failed:" + error); Console.WriteLine("Pack failed:" + error); throw new ApplicationException("Pack failed:" + error); // throw } string bundleMapPath = GetBuildBundleMapPath(target); bool doIndexSucceed = DoSqliteBundleIndexMap(bundleMapPath, target, buildManifest); //跟exp_bundle同目录 string dynamicPath = PathConfig.GetDynamicIndicesBundlePath(target); if (Directory.Exists(dynamicPath)) { EngineCore.EngineFileUtil.DeleteDirectory(dynamicPath); } Directory.CreateDirectory(dynamicPath); EngineCore.EngineFileUtil.CopyDirectory(bundleMapPath, dynamicPath); //Release 资源裁减 if (isReleaseBuild) { bool isSuccessed = StrippingResourcesForRelease(target, bundleMapPath); if (!isSuccessed) { Debug.LogError("打包" + GOEPackV5.GetPlatformName(target) + "release 失败,请配置AssetManifest.xls"); return; } } AssetDatabase.Refresh(); if (doIndexSucceed) { Debug.Log("打包" + GOEPackV5.GetPlatformName(target) + "完毕"); } } catch (Exception ex) { Console.WriteLine("pack error:"); Console.WriteLine("打包" + GOEPackV5.GetPlatformName(target) + $"失败, {ex.Message}"); throw; } }