private void OnGUI() { GUILayout.Label("保存路径"); GUILayout.BeginHorizontal(); path = GUILayout.TextField(path); if (GUILayout.Button("选择文件夹")) { string selectPath = EditorUtility.OpenFolderPanel("资源保持路径", Application.dataPath, ""); if (!string.IsNullOrEmpty(selectPath)) { path = selectPath; } } GUILayout.EndHorizontal(); GUILayout.Label("打包平台"); platform = (BuildTarget)EditorGUILayout.EnumPopup(platform); GUILayout.Label("压缩方式"); option = (BuildAssetBundleOptions)EditorGUILayout.EnumPopup(option); scrollPos = GUILayout.BeginScrollView(scrollPos); for (int i = 0; i < bundles.Length; i++) { bool isBuild = selectBunldes.Contains(bundles[i]); bool isTrue = GUILayout.Toggle(isBuild, bundles[i]); if (isBuild != isTrue) { if (isTrue) { selectBunldes.Add(bundles[i]); } else { selectBunldes.Remove(bundles[i]); } } } GUILayout.EndScrollView(); GUILayout.Label("版本信息"); version = GUILayout.TextField(version); // if (GUILayout.Button("生成Hotfix字节文件")) // { // GenHotfix(); // AssetDatabase.Refresh(); // } if (GUILayout.Button("打包")) { AssetBundleBuild[] builds = new AssetBundleBuild[selectBunldes.Count]; for (int i = 0; i < builds.Length; i++) { AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = selectBunldes[i]; build.assetNames = AssetDatabase.GetAssetPathsFromAssetBundle(build.assetBundleName); builds[i] = build; } AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(GetTargetPath(platform), builds, option, platform); Dictionary <string, Hash128> hash = FileUtil.LoadABManifest(manifest); CreateConfig(hash); AssetDatabase.Refresh(); } }
/// <summary> /// Collect CPU combinations for the specified TargetPlatform and TargetCPU /// </summary> /// <param name="targetPlatform">The target platform (e.g Windows)</param> /// <param name="targetCpu">The target CPU (e.g X64_SSE4)</param> /// <param name="report">Error reporting</param> /// <returns>The list of CPU combinations</returns> private static List <BurstOutputCombination> CollectCombinations(TargetPlatform targetPlatform, TargetCpu targetCpu, BuildReport report) { var combinations = new List <BurstOutputCombination>(); if (targetPlatform == TargetPlatform.macOS) { // NOTE: OSX has a special folder for the plugin // Declared in GetStagingAreaPluginsFolder // PlatformDependent\OSXPlayer\Extensions\Managed\OSXDesktopStandalonePostProcessor.cs #if UNITY_2019_3_OR_NEWER combinations.Add(new BurstOutputCombination(Path.Combine(Path.GetFileName(report.summary.outputPath), "Contents", "Plugins"), targetCpu)); #else combinations.Add(new BurstOutputCombination("UnityPlayer.app/Contents/Plugins", targetCpu)); #endif } else if (targetPlatform == TargetPlatform.iOS) { if (Application.platform != RuntimePlatform.OSXEditor) { Debug.LogWarning("Burst Cross Compilation to iOS for standalone player, is only supported on OSX Editor at this time, burst is disabled for this build."); } else { var targetArchitecture = (IOSArchitecture)UnityEditor.PlayerSettings.GetArchitecture(report.summary.platformGroup); if (targetArchitecture == IOSArchitecture.ARMv7 || targetArchitecture == IOSArchitecture.Universal) { // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV7A_NEON32, DefaultLibraryName + "32")); } if (targetArchitecture == IOSArchitecture.ARM64 || targetArchitecture == IOSArchitecture.Universal) { // PlatformDependent\iPhonePlayer\Extensions\Common\BuildPostProcessor.cs combinations.Add(new BurstOutputCombination("StaticLibraries", TargetCpu.ARMV8A_AARCH64, DefaultLibraryName + "64")); } } } else if (targetPlatform == TargetPlatform.Android) { // TODO: would be better to query AndroidNdkRoot (but thats not exposed from unity) string ndkRoot = null; var targetAPILevel = PlayerSettings.Android.GetMinTargetAPILevel(); #if UNITY_2019_3_OR_NEWER && UNITY_ANDROID ndkRoot = UnityEditor.Android.AndroidExternalToolsSettings.ndkRootPath; #elif UNITY_2019_1_OR_NEWER // 2019.1 now has an embedded ndk if (EditorPrefs.HasKey("NdkUseEmbedded")) { if (EditorPrefs.GetBool("NdkUseEmbedded")) { ndkRoot = Path.Combine(BuildPipeline.GetPlaybackEngineDirectory(BuildTarget.Android, BuildOptions.None), "NDK"); } else { ndkRoot = EditorPrefs.GetString("AndroidNdkRootR16b"); } } #endif // If we still don't have a valid root, try the old key if (string.IsNullOrEmpty(ndkRoot)) { ndkRoot = EditorPrefs.GetString("AndroidNdkRoot"); } // Verify the directory at least exists, if not we fall back to ANDROID_NDK_ROOT current setting if (!string.IsNullOrEmpty(ndkRoot) && !Directory.Exists(ndkRoot)) { ndkRoot = null; } // Always set the ANDROID_NDK_ROOT (if we got a valid result from above), so BCL knows where to find the Android toolchain and its the one the user expects if (!string.IsNullOrEmpty(ndkRoot)) { Environment.SetEnvironmentVariable("ANDROID_NDK_ROOT", ndkRoot); } Environment.SetEnvironmentVariable("BURST_ANDROID_MIN_API_LEVEL", $"{targetAPILevel}"); var androidTargetArch = UnityEditor.PlayerSettings.Android.targetArchitectures; if ((androidTargetArch & AndroidArchitecture.ARMv7) != 0) { combinations.Add(new BurstOutputCombination("libs/armeabi-v7a", TargetCpu.ARMV7A_NEON32)); } if ((androidTargetArch & AndroidArchitecture.ARM64) != 0) { combinations.Add(new BurstOutputCombination("libs/arm64-v8a", TargetCpu.ARMV8A_AARCH64)); } #if !UNITY_2019_2_OR_NEWER if ((androidTargetArch & AndroidArchitecture.X86) != 0) { combinations.Add(new BurstOutputCombination("libs/x86", TargetCpu.X86_SSE2)); } #endif } else if (targetPlatform == TargetPlatform.UWP) { // TODO: Make it configurable for x86 (sse2, sse4) combinations.Add(new BurstOutputCombination("Plugins/x64", TargetCpu.X64_SSE4)); combinations.Add(new BurstOutputCombination("Plugins/x86", TargetCpu.X86_SSE2)); combinations.Add(new BurstOutputCombination("Plugins/ARM", TargetCpu.THUMB2_NEON32)); combinations.Add(new BurstOutputCombination("Plugins/ARM64", TargetCpu.ARMV8A_AARCH64)); } else if (targetPlatform == TargetPlatform.Lumin) { // Set the LUMINSDK_UNITY so bcl.exe will be able to find the SDK if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("LUMINSDK_UNITY"))) { var sdkRoot = EditorPrefs.GetString("LuminSDKRoot"); if (!string.IsNullOrEmpty(sdkRoot)) { Environment.SetEnvironmentVariable("LUMINSDK_UNITY", sdkRoot); } } combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu)); } else if (targetPlatform == TargetPlatform.Switch) { combinations.Add(new BurstOutputCombination("NativePlugins/", targetCpu)); } #if UNITY_2019_3_OR_NEWER else if (targetPlatform == TargetPlatform.Stadia) { combinations.Add(new BurstOutputCombination("NativePlugins", targetCpu)); } #endif else { combinations.Add(new BurstOutputCombination("Data/Plugins/", targetCpu)); } return(combinations); }
public static void ProcUIScene(List <string> specialList, List <string> uiScenePrefabList, List <string> prefabList) { AssetBundleConfig uiConfig = new AssetBundleConfig(); //UI配置文件 AssetBundleConfig prefabConfig = new AssetBundleConfig(); //动态Prefab配置文件 Dictionary <string, AssetBundleType> allAssetBundleMap = new Dictionary <string, AssetBundleType>(); //记录所有打包的Asset List <string> comAssetList = new List <string>(); //记录所有公共资源 List <string> ignoreBundleList = new List <string>(); //需要删除的资源 #if PACKAGE_BASIC //添加小包过滤操作 Dictionary <string, string> extendAssetMap = new Dictionary <string, string>(); List <string> basicAssetList = new List <string>(); #endif //开始打包资源 BuildPipeline.PushAssetDependencies(); //打包部分指定Shader List <string> shdList = BuildShader.BuildAllShader("all"); //打包Special Texture foreach (string texturePath in specialList) { string sTemp = texturePath.Replace('\\', '/'); int startIndex = sTemp.LastIndexOf('/') + 1; int endIndex = sTemp.LastIndexOf('.') - 1; string textureName = sTemp.Substring(startIndex, endIndex - startIndex + 1); if (!allAssetBundleMap.ContainsKey(textureName)) { string parentPath = GetParentPath(texturePath); if (!Directory.Exists(parentPath)) { Directory.CreateDirectory(parentPath); } if (!BuildAssetBundle.IsLegalAsset(textureName)) { Debug.LogError("Build ui error, asset name is not all lower," + texturePath); EditorUtility.DisplayDialog("Error", "Build ui error, asset name is not all lower,Please try again!" + texturePath, "OK"); return; } Texture2D tex2D = AssetDatabase.LoadAssetAtPath(texturePath, typeof(Texture2D)) as Texture2D; string path = parentPath + textureName + "." + AssetBundleType.Texture.ToString().ToLower(); BuildAssetBundle.Build(tex2D, null, path, true); allAssetBundleMap.Add(textureName, AssetBundleType.Texture); } } //获取依赖关系 Dictionary <string, List <DependencyAsset> > prefabAssetRefMap = BuildAssetBundle.GetAssetDependencieRefs(prefabList.ToArray()); //获取动态Prefab依赖关系 Dictionary <string, List <DependencyAsset> > uiAssetRefMap = BuildAssetBundle.GetAssetDependencieRefs(uiScenePrefabList.ToArray()); //获取UI依赖关系 Dictionary <string, List <DependencyAsset> > allAssetRefMap = new Dictionary <string, List <DependencyAsset> >(uiAssetRefMap); if (prefabAssetRefMap != null && prefabAssetRefMap.Count > 0) { foreach (string prefabPath in prefabAssetRefMap.Keys) { if (!allAssetRefMap.ContainsKey(prefabPath)) { allAssetRefMap.Add(prefabPath, prefabAssetRefMap[prefabPath]); } } } //排序 List <string> allAssetRefKeyList = null; if (allAssetRefMap != null && allAssetRefMap.Count > 0) { allAssetRefKeyList = new List <string>(allAssetRefMap.Keys); allAssetRefKeyList.Sort(new UICompare()); } //获取所有脚本 if (allAssetRefKeyList != null && allAssetRefKeyList.Count > 0) { foreach (string uiscenePath in allAssetRefKeyList) { List <DependencyAsset> val = allAssetRefMap[uiscenePath]; foreach (DependencyAsset dasset in val) { string sceneDepPath = dasset.AssetPath; AssetBundleType assetType = dasset.AssetType; if (assetType == AssetBundleType.Script) { if (!comAssetList.Contains(sceneDepPath)) { comAssetList.Add(sceneDepPath); } } else if (assetType == AssetBundleType.ScriptDLL) { string dllPath = AssetBundlePath.DLLPrefabAssetDir + dasset.AssetName + ".prefab"; if (File.Exists(dllPath)) { if (!comAssetList.Contains(dllPath)) { comAssetList.Add(dllPath); } } else { Debug.LogError("Build UI failed. Can not find dll file prefab, path=" + dllPath); } } } } } //打包公共资源 if (comAssetList != null && comAssetList.Count > 0) { //创建界面目录 string comParentPath = AssetBundlePath.UIAssetRootPath + AssetBundleType.Scene + "/"; //场景目录 if (!Directory.Exists(comParentPath)) { Directory.CreateDirectory(comParentPath); } List <Object> comObjectList = new List <Object>(); for (int i = 0; i < comAssetList.Count; ++i) { comObjectList.Add(AssetDatabase.LoadAssetAtPath(comAssetList[i], typeof(Object))); } BuildAssetBundle.Build(null, comObjectList.ToArray(), comParentPath + "ui_common" + "." + AssetBundleType.Scene.ToString().ToLower(), true); comObjectList.Clear(); } //打包其他资源 if (allAssetRefKeyList != null && allAssetRefKeyList.Count > 0) { foreach (string rootAssetPath in allAssetRefKeyList) { AssetBundleConfig bundleConfig = null; string rootAssetName = BuildAssetBundle.GetAssetName(rootAssetPath); AssetBundleType rootAssetType = BuildAssetBundle.GetAssetType(rootAssetPath); //确定配置文件 if (uiScenePrefabList.Contains(rootAssetPath)) { bundleConfig = uiConfig; } else if (prefabList.Contains(rootAssetPath)) { bundleConfig = prefabConfig; } else { Debug.LogError("Build ui error, can not find current assetType," + rootAssetType + "," + rootAssetPath); } List <DependencyAsset> depList = allAssetRefMap[rootAssetPath]; for (int i = 0; i < depList.Count; ++i) { DependencyAsset dasset = depList[i]; AssetBundleType arType = dasset.AssetType; string assetName = dasset.AssetName; string assetFullName = dasset.AssetName + "." + dasset.AssetSuffix; string assetPath = dasset.AssetPath; string bundleParentPath = AssetBundlePath.UIAssetRootPath + arType + "/"; string bundlePath = bundleParentPath + assetName + "." + arType.ToString().ToLower(); bool popDependence = false; if (arType == AssetBundleType.Max) { Debug.LogError("BuildUI error, unSupport assetBundle," + rootAssetPath); } if (IgnoreAssetList.Contains(assetFullName)) { if (!ignoreBundleList.Contains(bundlePath)) { ignoreBundleList.Add(bundlePath); } } else { if (rootAssetName.Equals(assetName)) { popDependence = true; } else if (dasset.IsLeaf || assetPath.Replace('\\', '/').Contains(AssetBundlePath.ArtUIDir)) { if (arType == AssetBundleType.Script || arType == AssetBundleType.ScriptDLL) { continue; } else if (arType == AssetBundleType.Shd && shdList.Contains(assetFullName)) { //忽略已经打包的Shader,此操作为了兼容旧版本 continue; } } else { continue; } bundleConfig.AddConfig(rootAssetName, arType, assetName, i); } if (!allAssetBundleMap.ContainsKey(assetName)) { if (!BuildAssetBundle.IsLegalAsset(assetName)) { Debug.LogError("Build ui error, asset name is not all lower," + assetPath); EditorUtility.DisplayDialog("Error", "Build ui error, asset name is not all lower,Please try again!" + assetPath, "OK"); return; } BuildBundle(assetPath, bundleParentPath, bundlePath, dasset.IsLeaf, popDependence); allAssetBundleMap.Add(assetName, arType); #if PACKAGE_BASIC //记录扩展包资源 if (IsExtendPackageScene(rootAssetPath) && !extendAssetMap.ContainsKey(assetPath)) { if (specialList.Contains(assetPath)) { //Check it again. Debug.LogError("Special texture dictionary has same texture,TexturePath=" + assetPath + ".UIScenePath=" + rootAssetPath); } else { extendAssetMap.Add(assetPath, bundlePath); } } //记录小包资源 if (IsBasicPackageScene(rootAssetPath) && !basicAssetList.Contains(assetPath)) { basicAssetList.Add(assetPath); } #endif } else { AssetBundleType usedType = allAssetBundleMap[assetName]; if (usedType != arType) { Debug.LogError("Build UI error, same asset name has been found.AssetName=" + assetName + "." + arType + "," + assetName + "." + usedType + ".UIPath=" + rootAssetPath); } } } } } //保存UI界面配置文件 if (uiScenePrefabList != null && uiScenePrefabList.Count > 0) { string uisceneParentPath = AssetBundlePath.UIAssetRootPath + AssetBundleType.Scene + "/"; //场景目录 if (!Directory.Exists(uisceneParentPath)) { Directory.CreateDirectory(uisceneParentPath); } uiConfig.SaveConfig(uisceneParentPath + "uiconfig.txt"); } else { Debug.Log("Build UI tips:no scene found."); } //保存Prefab配置文件 if (prefabList != null && prefabList.Count > 0) { string prefabconfigParentPath = AssetBundlePath.UIAssetRootPath + AssetBundleType.Scene + "/"; if (!Directory.Exists(prefabconfigParentPath)) { Directory.CreateDirectory(prefabconfigParentPath); } prefabConfig.SaveConfig(prefabconfigParentPath + "uiprefabconfig.txt"); } else { Debug.Log("Build UI tips:no dynamic prefab found."); } //删除忽略的资源 foreach (string delPath in ignoreBundleList) { if (!string.IsNullOrEmpty(delPath)) { File.Delete(delPath); } } #if PACKAGE_BASIC //过滤小包中用到的资源 foreach (string basicAssetPath in basicAssetList) { if (extendAssetMap.ContainsKey(basicAssetPath)) { extendAssetMap.Remove(basicAssetPath); } } //删除扩展包资源 foreach (string path in extendAssetMap.Values) { if (string.IsNullOrEmpty(path)) { Debug.LogError("Build basic package error, can not delete unuse texture"); } else { File.Delete(path); } } #endif //结束打包资源 BuildPipeline.PopAssetDependencies(); AssetDatabase.Refresh(); }
static void PerformAndroidBuild() { EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTarget.Android); Directory.CreateDirectory("Builds"); BuildPipeline.BuildPlayer(GetScenePaths(), "Builds/Android.apk", BuildTarget.Android, BuildOptions.None); }
private static bool BuildAssetBundle(string[] assetsList, string outputPath, out uint crc) { crc = 0; // Load all of assets in this bundle List <UnityEngine.Object> assets = new List <UnityEngine.Object>(); List <string> assetPathNews = new List <string>(); foreach (string assetPath in assetsList) { //dll�ļ������ string assetEx = Path.GetExtension(assetPath); string assetPathNew = assetPath; if (string.Compare(assetEx, ".dll", StringComparison.OrdinalIgnoreCase) == 0) { string assetName = Path.GetFileNameWithoutExtension(assetPath); string assetDic = Path.GetDirectoryName(assetPath); assetPathNew = assetDic + "/" + assetName + ".bytes"; //FileUtil.CopyFileOrDirectory(assetPath, assetPathNew); File.Copy(assetPath, assetPathNew); assetPathNews.Add(assetPathNew); AssetDatabase.Refresh(); } UnityEngine.Object[] assetsAtPath = AssetDatabase.LoadAllAssetsAtPath(assetPathNew); if (assetsAtPath != null || assetsAtPath.Length != 0) { assets.AddRange(assetsAtPath); } else { Debug.LogError("Cannnot load [" + assetPathNew + "] as asset object"); } } // Build bundle //#if UNITY_4_2 || UNITY_4_1 || UNITY_4_0 // bool succeed = BuildPipeline.BuildAssetBundle( null, // assets.ToArray(), // outputPath, // CurrentBuildAssetOpts, // BuildConfiger.UnityBuildTarget); //#else bool succeed = BuildPipeline.BuildAssetBundle(null, assets.ToArray(), outputPath, #if UNITY_WEBPLAYER out crc, #endif CurrentBuildAssetOpts, BuildConfiger.UnityBuildTarget); //#endif #if UNITY_STANDALONE_WIN crc = Crc32.GetFileCRC32(outputPath); #endif if (assetPathNews.Count != 0) { foreach (string path in assetPathNews) { File.Delete(path); } AssetDatabase.Refresh(); } return(succeed); }
public static void PushAssetBundle(Object asset, string path) { BuildPipeline.PushAssetDependencies(); BuildAssetBundle(asset, path); PushedAssetCount++; }
/// <summary> /// Builds a single APK and places it in the build folder. /// </summary> /// <param name="settings">Description of the APK to build.</param> public static void BuildAPK(APKSettings settings) { // Don't make any permanent changes to the player settings! Texture2D[] oldIcons = PlayerSettings.GetIconsForTargetGroup(BuildTargetGroup.Android); string oldKeystoreName = PlayerSettings.Android.keystoreName; string oldkeyaliasName = PlayerSettings.Android.keyaliasName; string oldKeystorePass = PlayerSettings.Android.keystorePass; string oldKeyaliasPass = PlayerSettings.Android.keyaliasPass; string oldProductName = PlayerSettings.productName; string oldBundleIdentifier = PlayerSettings.bundleIdentifier; string oldAndroidSdkRoot = EditorPrefs.GetString("AndroidSdkRoot"); // make sure the product folder exists System.IO.Directory.CreateDirectory(BUILD_APK_DIRECTORY_W_SLASH); // set icons (Android currently supports 6 sizes) Texture2D icon = (Texture2D)AssetDatabase.LoadMainAssetAtPath(ASSET_DIRECTORY_W_SLASH + settings.Icon); PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Android, new Texture2D[] { icon, icon, icon, icon, icon, icon }); string keystoreDir = FindKeystoreDirectory(); if (keystoreDir != null) { string keystorePass = ReadKeystorePassword(keystoreDir + "/trailmix-release-key-password.txt"); PlayerSettings.Android.keystoreName = keystoreDir + "/trailmix-release-key.keystore"; PlayerSettings.Android.keyaliasName = "alias_name"; PlayerSettings.Android.keystorePass = PlayerSettings.Android.keyaliasPass = keystorePass; } // set name and ids PlayerSettings.productName = settings.ProjectName; PlayerSettings.bundleIdentifier = settings.BundleIdentifier; // Unity won't remember where the Android SDK was when built on Jenkins string sdkRoot = Environment.GetEnvironmentVariable("ANDROID_SDK_ROOT"); if (sdkRoot != String.Empty) { EditorPrefs.SetString("AndroidSdkRoot", sdkRoot); } // and finally... build it! string[] scenesUnityPath = new string[settings.Scenes.Length]; for (int it = 0; it != settings.Scenes.Length; ++it) { scenesUnityPath[it] = ASSET_DIRECTORY_W_SLASH + settings.Scenes[it]; } BuildPipeline.BuildPlayer(scenesUnityPath, BUILD_APK_DIRECTORY_W_SLASH + settings.ProjectName + ".apk", BuildTarget.Android, BuildOptions.None); // Restore player settings PlayerSettings.SetIconsForTargetGroup(BuildTargetGroup.Android, oldIcons); PlayerSettings.Android.keystoreName = oldKeystoreName; PlayerSettings.Android.keyaliasName = oldkeyaliasName; PlayerSettings.Android.keystorePass = oldKeystorePass; PlayerSettings.Android.keyaliasPass = oldKeyaliasPass; PlayerSettings.productName = oldProductName; PlayerSettings.bundleIdentifier = oldBundleIdentifier; EditorPrefs.SetString("AndroidSdkRoot", oldAndroidSdkRoot); }
private static void RunAssemblyStripper(UnityLinkerRunInformation runInformation) { string output; string error; var rcr = runInformation.rcr; var managedAssemblyFolderPath = runInformation.managedAssemblyFolderPath; var linkXmlFiles = new List <string>(); linkXmlFiles.AddRange(Il2CppBlacklistPaths); if (rcr != null) { linkXmlFiles.Add(WriteMethodsToPreserveBlackList(rcr, runInformation.target)); linkXmlFiles.Add(MonoAssemblyStripping.GenerateLinkXmlToPreserveDerivedTypes(managedAssemblyFolderPath, rcr)); linkXmlFiles.Add(WriteTypesInScenesBlacklist(managedAssemblyFolderPath, rcr)); } linkXmlFiles.AddRange(ProcessBuildPipelineGenerateAdditionalLinkXmlFiles(runInformation)); linkXmlFiles.AddRange(GetUserBlacklistFiles()); if (runInformation.isMonoBackend) { // The old Mono assembly stripper uses per-platform link.xml files if available. Apply these here. var buildToolsDirectory = BuildPipeline.GetBuildToolsDirectory(runInformation.target); if (!string.IsNullOrEmpty(buildToolsDirectory)) { var platformDescriptor = Path.Combine(buildToolsDirectory, "link.xml"); if (File.Exists(platformDescriptor)) { linkXmlFiles.Add(platformDescriptor); } } } WriteEditorData(runInformation); if (!runInformation.performEngineStripping && !UseUnityLinkerEngineModuleStripping) { // if we don't do stripping, add all modules blacklists. linkXmlFiles.AddRange(runInformation.GetModuleBlacklistFiles()); } var tempStripPath = Path.GetFullPath(Path.Combine(managedAssemblyFolderPath, "tempStrip")); ProcessBuildPipelineOnBeforeRun(runInformation); bool addedMoreBlacklists; do { addedMoreBlacklists = false; if (EditorUtility.DisplayCancelableProgressBar("Building Player", "Stripping assemblies", 0.0f)) { throw new OperationCanceledException(); } if (!StripAssembliesTo( tempStripPath, out output, out error, SanitizeLinkXmlFilePaths(linkXmlFiles, runInformation), runInformation)) { throw new Exception("Error in stripping assemblies: " + runInformation.AssembliesToProcess() + ", " + error); } if (runInformation.engineStrippingSupported) { var icallSummaryPath = Path.Combine(managedAssemblyFolderPath, "ICallSummary.txt"); GenerateInternalCallSummaryFile(icallSummaryPath, managedAssemblyFolderPath, tempStripPath); if (runInformation.performEngineStripping && !UseUnityLinkerEngineModuleStripping) { // Find which modules we must include in the build based on Assemblies HashSet <UnityType> nativeClasses; HashSet <string> nativeModules; CodeStrippingUtils.GenerateDependencies(tempStripPath, icallSummaryPath, rcr, runInformation.performEngineStripping, out nativeClasses, out nativeModules, runInformation.il2CppPlatformProvider); // Add module-specific blacklists. addedMoreBlacklists = AddWhiteListsForModules(nativeModules, linkXmlFiles, runInformation.platformProvider.moduleStrippingInformationFolder); } } if (runInformation.performEngineStripping && UseUnityLinkerEngineModuleStripping) { UpdateBuildReport(ReadLinkerToEditorData(tempStripPath), runInformation); } // If we had to add more whitelists, we need to run AssemblyStripper again with the added whitelists. }while (addedMoreBlacklists && !UseUnityLinkerEngineModuleStripping); // keep unstripped files for debugging purposes var tempUnstrippedPath = Path.GetFullPath(Path.Combine(managedAssemblyFolderPath, "tempUnstripped")); if (debugUnstripped) { Directory.CreateDirectory(tempUnstrippedPath); } foreach (var file in Directory.GetFiles(managedAssemblyFolderPath)) { var extension = Path.GetExtension(file); if (string.Equals(extension, ".dll", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".winmd", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".mdb", StringComparison.InvariantCultureIgnoreCase) || string.Equals(extension, ".pdb", StringComparison.InvariantCultureIgnoreCase)) { if (debugUnstripped) { File.Move(file, Path.Combine(tempUnstrippedPath, Path.GetFileName(file))); } else { File.Delete(file); } } } foreach (var file in Directory.GetFiles(tempStripPath)) { File.Move(file, Path.Combine(managedAssemblyFolderPath, Path.GetFileName(file))); } foreach (var dir in Directory.GetDirectories(tempStripPath)) { Directory.Move(dir, Path.Combine(managedAssemblyFolderPath, Path.GetFileName(dir))); } Directory.Delete(tempStripPath); ProcessBuildPipelineOnAfterRun(runInformation); }
static void BuildAllAssetBundles() { string outPath = PathUtil.GetAssetBundleOutPath(); BuildPipeline.BuildAssetBundles(outPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); }
// [MenuItem("AssetBundle/生成 Module Bundles")] static void CreateMoudleBundle() { Stopwatch stopwatch = Stopwatch.StartNew(); List <AssetBundleBuild> bundleList = new List <AssetBundleBuild>(); string[] files = Directory.GetFiles(UiSpriteAtlasPath, "*.*", SearchOption.AllDirectories); foreach (var file in files) { string filePath = file.Replace("\\", "/"); if (file.LastIndexOf(".meta", StringComparison.Ordinal) != -1) { continue; } if (filePath.EndsWith(".spriteatlas") == false) { continue; } AssetBundleBuild bundle = CreateUiAtlas(filePath); bundleList.Add(bundle); } files = Directory.GetFiles(FontPath, "*.*", SearchOption.AllDirectories); foreach (var file in files) { string filePath = file.Replace("\\", "/"); if (file.LastIndexOf(".meta", StringComparison.Ordinal) != -1) { continue; } AssetBundleBuild bundle = CreateSingleFile(filePath); bundleList.Add(bundle); } files = Directory.GetFiles(ModulePath, "*.*", SearchOption.AllDirectories); foreach (var file in files) { string filePath = file.Replace("\\", "/"); if (file.LastIndexOf(".meta", StringComparison.Ordinal) != -1) { continue; } AssetBundleBuild bundle = CreateModule(filePath); bundleList.Add(bundle); } CheckAndCreateDir(GetBundleOutputPath()); AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(GetBundleOutputPath(), bundleList.ToArray(), BuildAssetBundleOptions.UncompressedAssetBundle, EditorUserBuildSettings.activeBuildTarget); Debug.Log("<color='#00ff66'>Bundle数量:" + bundleList.Count + " ====== 耗时: " + (float)stopwatch.ElapsedMilliseconds / 1000 + "</color>"); }
static void CreateAllBundle() { Stopwatch stopwatch = Stopwatch.StartNew(); List <AssetBundleBuild> bundleList = new List <AssetBundleBuild>(); string[] files = Directory.GetFiles(BundleRoot, "*.*", SearchOption.AllDirectories); foreach (var file in files) { if (file.LastIndexOf(".meta", StringComparison.Ordinal) != -1) { continue; } string filePath = file.Replace("\\", "/"); AssetBundleBuild bundle = new AssetBundleBuild(); if (filePath.StartsWith(SingleFilePath)) { bundle = CreateSingleFile(filePath); } else if (filePath.StartsWith(ModulePath)) { bundle = CreateModule(filePath); } else if (filePath.StartsWith(AudioPath)) { bundle = CreateAudio(filePath); } else if (filePath.StartsWith(UiSpriteAtlasPath)) { if (filePath.EndsWith(".spriteatlas") == false) { continue; } bundle = CreateUiAtlas(filePath); } else if (filePath.StartsWith(StoryPath)) { bundle = CreateStory(filePath); } if (string.IsNullOrEmpty(bundle.assetBundleName)) { continue; } bundleList.Add(bundle); } CheckAndCreateDir(GetBundleOutputPath()); AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(GetBundleOutputPath(), bundleList.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression | BuildAssetBundleOptions.DeterministicAssetBundle, EditorUserBuildSettings.activeBuildTarget); Debug.Log("<color='#00ff66'>Bundle数量:" + bundleList.Count + " ====== 耗时: " + (float)stopwatch.ElapsedMilliseconds / 1000 + "</color>"); }
static void TestLightmapData() { try { string scene = SceneManager.GetActiveScene().name; string asset_path = "Assets/" + scene + ".bytes"; string record = Path.Combine(Application.dataPath, scene + ".bytes"); List <string> assetNames = new List <string>(); assetNames.Add(asset_path); EditorUtility.DisplayProgressBar("build lightmap", "正在生成lightmap相关配置", 0.1f); FileStream fs = new FileStream(record, FileMode.OpenOrCreate, FileAccess.Write); BinaryWriter writer = new BinaryWriter(fs); int cnt = LightmapSettings.lightmaps.Length; Debug.Log("map cnt: " + cnt); writer.Write(cnt); Texture2D[] lmColors = new Texture2D[cnt]; Texture2D[] lmDirs = new Texture2D[cnt]; for (int i = 0; i < cnt; i++) { lmColors[i] = LightmapSettings.lightmaps[i].lightmapColor; lmDirs[i] = LightmapSettings.lightmaps[i].lightmapDir; writer.Write(lmColors[i] == null ? "" : lmColors[i].name); writer.Write(lmDirs[i] == null ? "" : lmDirs[i].name); if (lmColors[i] != null) { assetNames.Add(AssetDatabase.GetAssetPath(lmColors[i])); } if (lmDirs[i] != null) { assetNames.Add(AssetDatabase.GetAssetPath(lmDirs[i])); } } RecordLightmapOffset(writer); writer.Flush(); writer.Close(); fs.Close(); AssetDatabase.ImportAsset(asset_path); string exportTargetPath = Application.dataPath + "/StreamingAssets/"; Debug.Log(exportTargetPath); if (!Directory.Exists(exportTargetPath)) { Directory.CreateDirectory(exportTargetPath); } EditorUtility.DisplayProgressBar("build lightmap", "正在生成lightmap assetbundle", 0.4f); List <AssetBundleBuild> list = new List <AssetBundleBuild>(); AssetBundleBuild build = new AssetBundleBuild(); build.assetBundleName = scene + "_lightmap.ab"; build.assetNames = assetNames.ToArray(); list.Add(build); BuildPipeline.BuildAssetBundles(exportTargetPath, list.ToArray(), BuildAssetBundleOptions.UncompressedAssetBundle, EditorUserBuildSettings.activeBuildTarget); EditorUtility.DisplayProgressBar("build lightmap", "正在生成lightmap assetbundle", 0.9f); string orig = Path.Combine(Application.dataPath, "Scenes/" + scene); string dest = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "Lightmap/" + scene); if (Directory.Exists(dest)) { Directory.Delete(dest, true); } Directory.Move(orig, dest); AssetDatabase.DeleteAsset(asset_path); } catch (System.Exception e) { EditorUtility.DisplayDialog("error", e.Message, "ok"); Debug.LogError(e.StackTrace); } finally { EditorUtility.ClearProgressBar(); AssetDatabase.Refresh(); } }
static void BuildGameIOS(string[] levels) { BuildPipeline.BuildPlayer(levels, "ios", BuildTarget.iOS, BuildOptions.None); }
static void BuildGameAndroid(string[] levels, string platformName) { BuildPipeline.BuildPlayer(levels, string.Format("xfz_{0}.apk", platformName), BuildTarget.Android, BuildOptions.None); }
//アセットバンドルのビルド void BuildAssetBundles(string outPutDirectoryPath, FileIOManager fileIOManager, AssetFileManagerSettings settings, bool isOutputLog) { if (assetBundleBuildMode == AssetBundleBuildMode.None) { return; } //アセットバンドルをプラットフォーム別にビルド List <BuildTarget> buildTargets = new List <BuildTarget>(); switch (assetBundleBuildMode) { case AssetBundleBuildMode.OnlyEditor: //エディタ上のみ buildTargets.Add(EditorUserBuildSettings.activeBuildTarget); break; case AssetBundleBuildMode.AllPlatform: //全プラットフォーム { buildTargets = AssetBundleHelper.BuildTargetFlagsToBuildTargetList(buildTargetFlags); } break; default: break; } List <MainAssetInfo> assets = GetAssetBudleList(settings); RenameAssetBundles(assets); AssetBundleBuild[] builds = ToAssetBundleBuilds(assets); if (builds.Length <= 0) { return; } foreach (BuildTarget buildTarget in buildTargets) { string outputPath = FilePathUtil.Combine(outPutDirectoryPath, AssetBundleHelper.BuildTargetToBuildTargetFlag(buildTarget).ToString()); //出力先のディレクトリを作成 if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } //アセットバンドルを作成 AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(outputPath, builds, BuildAssetBundleOptions.None, buildTarget); //アセットバンドルの情報をバージョンアップ AdvFileListConverter converter = new AdvFileListConverter(outputPath, fileIOManager, settings); converter.VersionUp( (x) => { int count = x.ConvertFileList.EditorVersionUpAssetBundle(manifest, buildTarget); Debug.Log("" + count + " AsseBundle version up to target " + buildTarget.ToString()); }); if (isOutputLog) { converter.WriteLog(true); } } }
static void BuildAllAssetBundles() { BuildPipeline.BuildAssetBundles("Assets/StreamingAssets", BuildAssetBundleOptions.None, BuildTarget.WSAPlayer); }
public void OnPreprocessBuild(BuildTarget target, string path) { TriLibSettings.UpdateBatchSettings(); var pluginsBasePath = TriLibProjectUtils.FindPathRelativeToProject("Plugins"); var buildTarget = target; #endif if (buildTarget == BuildTarget.iOS) { #if TRILIB_USE_IOS_SIMULATOR var pluginsSuffix = ".debug.a"; #else var pluginsSuffix = "release.a"; #endif #if TRILIB_ENABLE_IOS_FILE_SHARING IOSFileSharingEnabled = true; #else IOSFileSharingEnabled = false; #endif var iOSImporters = PluginImporter.GetImporters(BuildTarget.iOS); foreach (var importer in iOSImporters) { if (importer.isNativePlugin) { if (importer.assetPath.StartsWith(string.Format((string)"{0}/iOS/", (object)pluginsBasePath))) { importer.SetIncludeInBuildDelegate(assetPath => importer.assetPath.EndsWith(pluginsSuffix)); } } } if (!UnityEditorInternal.InternalEditorUtility.inBatchMode) { #if UNITY_EDITOR_OSX EditorUtility.DisplayDialog("TriLib", "Warning: Bitcode is not supported by TriLib and will be disabled.", "Ok"); #else EditorUtility.DisplayDialog("TriLib", "Warning:\nBitcode is not supported. You should disable it on your project settings.", "Ok"); #endif } } var allImporters = PluginImporter.GetImporters(buildTarget); foreach (var importer in allImporters) { if (!importer.isNativePlugin) { if (importer.assetPath == string.Format((string)"{0}/ICSharpCode.SharpZipLib.dll", (object)pluginsBasePath)) { #if TRILIB_USE_ZIP importer.SetIncludeInBuildDelegate(assetPath => PlayerSettings.GetScriptingBackend(BuildPipeline.GetBuildTargetGroup(buildTarget)) != ScriptingImplementation.WinRTDotNET); #else importer.SetIncludeInBuildDelegate(assetPath => false); #endif } } } }
public static void PerformBuild(BuildInfo buildInfo) { BuildTargetGroup buildTargetGroup = GetGroup(buildInfo.BuildTarget); string oldBuildSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildTargetGroup); if (!string.IsNullOrEmpty(oldBuildSymbols)) { if (buildInfo.HasConfigurationSymbol()) { buildInfo.AppendSymbols(BuildInfo.RemoveConfigurationSymbols(oldBuildSymbols)); } else { buildInfo.AppendSymbols(oldBuildSymbols.Split(';')); } } if ((buildInfo.BuildOptions & BuildOptions.Development) == BuildOptions.Development) { if (!buildInfo.HasConfigurationSymbol()) { buildInfo.AppendSymbols(BuildSLNUtilities.BuildSymbolDebug); } } if (buildInfo.HasAnySymbols(BuildSLNUtilities.BuildSymbolDebug)) { buildInfo.BuildOptions |= BuildOptions.Development | BuildOptions.AllowDebugging; } if (buildInfo.HasAnySymbols(BuildSLNUtilities.BuildSymbolRelease)) { //Unity automatically adds the DEBUG symbol if the BuildOptions.Development flag is //specified. In order to have debug symbols and the RELEASE symbole we have to //inject the symbol Unity relies on to enable the /debug+ flag of csc.exe which is "DEVELOPMENT_BUILD" buildInfo.AppendSymbols("DEVELOPMENT_BUILD"); } var oldBuildTarget = EditorUserBuildSettings.activeBuildTarget; EditorUserBuildSettings.SwitchActiveBuildTarget(buildInfo.BuildTarget); var oldWSASDK = EditorUserBuildSettings.wsaSDK; if (buildInfo.WSASdk.HasValue) { EditorUserBuildSettings.wsaSDK = buildInfo.WSASdk.Value; } WSAUWPBuildType?oldWSAUWPBuildType = null; if (EditorUserBuildSettings.wsaSDK == WSASDK.UWP) { oldWSAUWPBuildType = EditorUserBuildSettings.wsaUWPBuildType; if (buildInfo.WSAUWPBuildType.HasValue) { EditorUserBuildSettings.wsaUWPBuildType = buildInfo.WSAUWPBuildType.Value; } } var oldWSAGenerateReferenceProjects = EditorUserBuildSettings.wsaGenerateReferenceProjects; if (buildInfo.WSAGenerateReferenceProjects.HasValue) { EditorUserBuildSettings.wsaGenerateReferenceProjects = buildInfo.WSAGenerateReferenceProjects.Value; } var oldColorSpace = PlayerSettings.colorSpace; if (buildInfo.ColorSpace.HasValue) { PlayerSettings.colorSpace = buildInfo.ColorSpace.Value; } if (buildInfo.BuildSymbols != null) { PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, buildInfo.BuildSymbols); } string buildError = "Error"; try { // For the WSA player, Unity builds into a target directory. // For other players, the OutputPath parameter indicates the // path to the target executable to build. if (buildInfo.BuildTarget == BuildTarget.WSAPlayer) { Directory.CreateDirectory(buildInfo.OutputDirectory); } OnPreProcessBuild(buildInfo); buildError = BuildPipeline.BuildPlayer( buildInfo.Scenes.ToArray(), buildInfo.OutputDirectory, buildInfo.BuildTarget, buildInfo.BuildOptions).name; if (buildError.StartsWith("Error")) { throw new Exception(buildError); } } finally { OnPostProcessBuild(buildInfo, buildError); PlayerSettings.colorSpace = oldColorSpace; PlayerSettings.SetScriptingDefineSymbolsForGroup(buildTargetGroup, oldBuildSymbols); EditorUserBuildSettings.wsaSDK = oldWSASDK; if (oldWSAUWPBuildType.HasValue) { EditorUserBuildSettings.wsaUWPBuildType = oldWSAUWPBuildType.Value; } EditorUserBuildSettings.wsaGenerateReferenceProjects = oldWSAGenerateReferenceProjects; EditorUserBuildSettings.SwitchActiveBuildTarget(oldBuildTarget); } }
public static void PopAssetBundle() { BuildPipeline.PopAssetDependencies(); PushedAssetCount--; }
public static void BuildAll() { //Debug.Log ("Application dataPath :" + Application.dataPath); BuildPipeline.BuildAssetBundles(Application.dataPath + "/../ab", BuildAssetBundleOptions.None, BuildTarget.Android); }
static void OnPostProcessBuild(BuildTarget target, string pathToBuiltProject) { if (s_ScenesWithARTypes.Count > 0 && s_SessionCount == 0) { var scenes = ""; foreach (var sceneName in s_ScenesWithARTypes) { scenes += string.Format("\n\t{0}", sceneName); } Debug.LogWarningFormat( "The following scenes contain AR components but no ARSession. The ARSession component controls the AR lifecycle, so these components will not do anything at runtime. Was this intended?{0}", scenes); } var generalSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget)); if (generalSettings != null && generalSettings.Manager != null && generalSettings.Manager.activeLoaders != null) { int loaderCount = generalSettings.Manager.activeLoaders.Count; if (loaderCount <= 0 && s_SessionCount > 0) { Debug.LogWarning( "There are scenes that contain an ARSession, but no XR plug-in providers have been selected for the current platform. To make a plug-in provider available at runtime go to Project Settings > XR Plug-in Management and enable at least one for the target platform."); } } s_ScenesWithARTypes.Clear(); s_SessionCount = 0; }
public static void BuildAndroid() { //string[] levels = {"Assets/Scene/Level_01.unity", "Assets/Scene/Level_02.unity"}; string[] levels = EditorBuildSettings.scenes.Where(s => s.enabled).Select(s => s.path).ToArray(); BuildPipeline.BuildPlayer(levels, "SHAFIK_IS_UNITY.apk", BuildTarget.Android, BuildOptions.None); }
static void PerformiOSBuild() { EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTarget.iOS); Directory.CreateDirectory("Builds"); BuildPipeline.BuildPlayer(GetScenePaths(), "Builds/iOS", BuildTarget.iOS, BuildOptions.None); }
static void ImportDatabase(bool assetsOnly) { string inputDirectory = "Assets/Input"; string bundleOutputDirectory = "Assets/Bundles"; string prefabTempDirectory = "Assets/Prefabs/FromImporter"; string bundleName = "elements.db"; int errorCount = 0; if (!Directory.Exists(inputDirectory)) { EditorUtility.DisplayDialog("Input Not Found", $"Input directory “{inputDirectory}” not found.", "Close"); return; } // Load JSON file to process. var jsonAssets = new List <TextAsset>(); foreach (string guid in AssetDatabase.FindAssets("t:TextAsset", new[] { inputDirectory })) { var assetPath = AssetDatabase.GUIDToAssetPath(guid); if (Path.GetExtension(assetPath).ToLower() == ".json") { jsonAssets.Add(AssetDatabase.LoadAssetAtPath <TextAsset>(assetPath)); } } if (jsonAssets.Count == 0) { EditorUtility.DisplayDialog("No Files", $"No JSON files were found in “{inputDirectory}”.", "Close"); return; } if (jsonAssets.Count > 1) { EditorUtility.DisplayDialog("Too Many Files", $"More than one JSON file found in “{inputDirectory}”.", "Close"); return; } // Parse the database from JSON. var fm = FeatureModel.FromJson(jsonAssets[0].text); // Generate prefab assets that will represent placeable elements at runtime. if (!Directory.Exists(prefabTempDirectory)) { Directory.CreateDirectory(prefabTempDirectory); } var generatedAssetPaths = new List <string>(); foreach (Feature feature in fm.FeatureMap.Values) { // Skip features that cannot be turned into prefabs. if (!feature.IsPhysical || feature.Metadata == null) { continue; } var prefab = new GameObject(feature.Name); var metadata = prefab.AddComponent <ElementMetadata>(); metadata.Init(feature); // Attach 3D model. string[] modelFileGUIDs = AssetDatabase.FindAssets(metadata.ModelFilename, new[] { inputDirectory }); if (modelFileGUIDs.Length == 0) { Debug.Log($"Could not find 3D model with name: {metadata.ModelFilename}"); Object.DestroyImmediate(prefab); errorCount++; continue; } var modelAsset = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(modelFileGUIDs[0])) as GameObject; if (modelAsset == null) { Debug.Log($"Model {metadata.ModelFilename} could not be loaded."); Object.DestroyImmediate(prefab); errorCount++; continue; } var model = Object.Instantiate(modelAsset, prefab.transform, false); if (model == null) { Debug.Log($"Model {metadata.ModelFilename} could not be instantiated."); Object.DestroyImmediate(prefab); errorCount++; continue; } model.name = "3D Model"; // Generate a collider mesh. var submeshes = model.GetComponentsInChildren <MeshFilter>(); var combine = new CombineInstance[submeshes.Length]; for (int i = 0; i < submeshes.Length; i++) { combine[i].mesh = submeshes[i].sharedMesh; combine[i].transform = submeshes[i].transform.localToWorldMatrix; } var combinedMesh = new Mesh(); combinedMesh.CombineMeshes(combine); prefab.AddComponent <ElementController>().SaveColliderMesh(combinedMesh); // Set AssetBundle label and save the prefab. bool saveSuccess; string prefabAssetPath = AssetDatabase.GenerateUniqueAssetPath($"{prefabTempDirectory}/{prefab.name}.prefab"); GameObject prefabAsset = PrefabUtility.SaveAsPrefabAsset(prefab, prefabAssetPath, out saveSuccess); if (prefabAsset == null || !saveSuccess) { Debug.Log($"Prefab {prefab.name} could not be saved as prefab asset."); Object.DestroyImmediate(prefab); errorCount++; continue; } AssetImporter.GetAtPath(prefabAssetPath).SetAssetBundleNameAndVariant(bundleName, ""); generatedAssetPaths.Add(prefabAssetPath); Object.DestroyImmediate(prefab); } // Mark linked textures to be put into the bundle. foreach (Feature feature in fm.FeatureMap.Values) { if (!feature.IsMaterial || feature.Material == null) { continue; } var textureFileGUIDs = AssetDatabase.FindAssets(feature.Material.TextureFilename, new[] { inputDirectory }); if (textureFileGUIDs.Length == 0) { Debug.Log($"Could not find texture with name: {feature.Material.TextureFilename}"); errorCount++; continue; } var assetPath = AssetDatabase.GUIDToAssetPath(textureFileGUIDs[0]); AssetImporter.GetAtPath(assetPath).SetAssetBundleNameAndVariant(bundleName, ""); } // Save the feature model as JSON asset. var featureModelJson = new TextAsset(jsonAssets[0].text); var featureModelSavePath = $"{prefabTempDirectory}/featuremodel.asset"; AssetDatabase.CreateAsset(featureModelJson, featureModelSavePath); AssetImporter.GetAtPath(featureModelSavePath).SetAssetBundleNameAndVariant(bundleName, ""); generatedAssetPaths.Add(featureModelSavePath); // If only prefabs were requested, we are done. if (assetsOnly) { return; } // Build the bundle. if (!Directory.Exists(bundleOutputDirectory)) { Directory.CreateDirectory(bundleOutputDirectory); } BuildPipeline.BuildAssetBundles(bundleOutputDirectory, BuildAssetBundleOptions.None, BuildTarget.Android); // AssetBundle is now saved. Delete the generated content. foreach (string path in generatedAssetPaths) { bool deleteSuccess = AssetDatabase.DeleteAsset(path); if (!deleteSuccess) { Debug.Log($"Failed to delete generated prefab asset at: {path}"); errorCount++; } } Directory.Delete(prefabTempDirectory, true); AssetDatabase.Refresh(); if (errorCount > 0) { EditorUtility.DisplayDialog("Import Errors", (errorCount == 1 ? "There was an error" : $"There were {errorCount} errors") + " during import." + "\nSee console log for more information.", "Close"); } else { EditorUtility.DisplayDialog("Import Complete", "Database was imported with no errors." + $"\nResults were saved to {bundleOutputDirectory}/{bundleName}", "Close"); } }
private void OnPostBuildPlayerScriptDLLsImpl(BuildReport report) { var aotSettingsForTarget = BurstPlatformAotSettings.GetOrCreateSettings(report.summary.platform); // Early exit if burst is not activated or the platform is not supported if (aotSettingsForTarget.DisableBurstCompilation || !IsSupportedPlatform(report.summary.platform)) { return; } var commonOptions = new List <string>(); var stagingFolder = Path.GetFullPath(TempStagingManaged); var playerAssemblies = GetPlayerAssemblies(report); // grab the location of the root of the player folder - for handling nda platforms that require keys var keyFolder = BuildPipeline.GetPlaybackEngineDirectory(report.summary.platform, BuildOptions.None); commonOptions.Add(GetOption(OptionAotKeyFolder, keyFolder)); commonOptions.Add(GetOption(OptionAotDecodeFolder, Path.Combine(Environment.CurrentDirectory, "Library", "Burst"))); // Extract the TargetPlatform and Cpu from the current build settings TargetCpu targetCpu; var targetPlatform = GetTargetPlatformAndDefaultCpu(report.summary.platform, out targetCpu); commonOptions.Add(GetOption(OptionPlatform, targetPlatform)); // -------------------------------------------------------------------------------------------------------- // 1) Calculate AssemblyFolders // These are the folders to look for assembly resolution // -------------------------------------------------------------------------------------------------------- var assemblyFolders = new List <string> { stagingFolder }; if (report.summary.platform == BuildTarget.WSAPlayer || report.summary.platform == BuildTarget.XboxOne) { // On UWP, not all assemblies are copied to StagingArea, so we want to // find all directories that we can reference assemblies from // If we don't do this, we will crash with AssemblyResolutionException // when following type references. foreach (var assembly in playerAssemblies) { foreach (var assemblyRef in assembly.compiledAssemblyReferences) { // Exclude folders with assemblies already compiled in the `folder` var assemblyName = Path.GetFileName(assemblyRef); if (assemblyName != null && File.Exists(Path.Combine(stagingFolder, assemblyName))) { continue; } var directory = Path.GetDirectoryName(assemblyRef); if (directory != null) { var fullPath = Path.GetFullPath(directory); if (IsMonoReferenceAssemblyDirectory(fullPath) || IsDotNetStandardAssemblyDirectory(fullPath)) { // Don't pass reference assemblies to burst because they contain methods without implementation // If burst accidentally resolves them, it will emit calls to burst_abort. fullPath = Path.Combine(EditorApplication.applicationContentsPath, "MonoBleedingEdge/lib/mono/unityaot"); fullPath = Path.GetFullPath(fullPath); // GetFullPath will normalize path separators to OS native format if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } fullPath = Path.Combine(fullPath, "Facades"); if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } else if (!assemblyFolders.Contains(fullPath)) { assemblyFolders.Add(fullPath); } } } } } // Copy assembly used during staging to have a trace if (BurstLoader.IsDebugging) { try { var copyAssemblyFolder = Path.Combine(Environment.CurrentDirectory, "Logs", "StagingAssemblies"); try { if (Directory.Exists(copyAssemblyFolder)) { Directory.Delete(copyAssemblyFolder); } } catch { } if (!Directory.Exists(copyAssemblyFolder)) { Directory.CreateDirectory(copyAssemblyFolder); } foreach (var file in Directory.EnumerateFiles(stagingFolder)) { File.Copy(file, Path.Combine(copyAssemblyFolder, Path.GetFileName(file))); } } catch { } } // -------------------------------------------------------------------------------------------------------- // 2) Calculate root assemblies // These are the assemblies that the compiler will look for methods to compile // This list doesn't typically include .NET runtime assemblies but only assemblies compiled as part // of the current Unity project // -------------------------------------------------------------------------------------------------------- var rootAssemblies = new List <string>(); foreach (var playerAssembly in playerAssemblies) { // the file at path `playerAssembly.outputPath` is actually not on the disk // while it is in the staging folder because OnPostBuildPlayerScriptDLLs is being called once the files are already // transferred to the staging folder, so we are going to work from it but we are reusing the file names that we got earlier var playerAssemblyPathToStaging = Path.Combine(stagingFolder, Path.GetFileName(playerAssembly.outputPath)); if (!File.Exists(playerAssemblyPathToStaging)) { Debug.LogWarning($"Unable to find player assembly: {playerAssemblyPathToStaging}"); } else { rootAssemblies.Add(playerAssemblyPathToStaging); } } commonOptions.AddRange(assemblyFolders.Select(folder => GetOption(OptionAotAssemblyFolder, folder))); // -------------------------------------------------------------------------------------------------------- // 3) Calculate the different target CPU combinations for the specified OS // // Typically, on some platforms like iOS we can be asked to compile a ARM32 and ARM64 CPU version // -------------------------------------------------------------------------------------------------------- var combinations = CollectCombinations(targetPlatform, targetCpu, report); // -------------------------------------------------------------------------------------------------------- // 4) Compile each combination // // Here bcl.exe is called for each target CPU combination // -------------------------------------------------------------------------------------------------------- string debugLogFile = null; if (BurstLoader.IsDebugging) { // Reset log files try { var logDir = Path.Combine(Environment.CurrentDirectory, "Logs"); debugLogFile = Path.Combine(logDir, "burst_bcl_editor.log"); if (!Directory.Exists(logDir)) { Directory.CreateDirectory(logDir); } File.WriteAllText(debugLogFile, string.Empty); } catch { debugLogFile = null; } } // Log the targets generated by BurstReflection.FindExecuteMethods foreach (var combination in combinations) { // Gets the output folder var stagingOutputFolder = Path.GetFullPath(Path.Combine(TempStaging, combination.OutputPath)); var outputFilePrefix = Path.Combine(stagingOutputFolder, combination.LibraryName); var options = new List <string>(commonOptions) { GetOption(OptionAotOutputPath, outputFilePrefix), GetOption(OptionTarget, combination.TargetCpu) }; if (targetPlatform == TargetPlatform.iOS || targetPlatform == TargetPlatform.Switch) { options.Add(GetOption(OptionStaticLinkage)); } // finally add method group options options.AddRange(rootAssemblies.Select(path => GetOption(OptionRootAssembly, path))); // Log the targets generated by BurstReflection.FindExecuteMethods if (BurstLoader.IsDebugging && debugLogFile != null) { try { var writer = new StringWriter(); writer.WriteLine("-----------------------------------------------------------"); writer.WriteLine("Combination: " + combination); writer.WriteLine("-----------------------------------------------------------"); foreach (var option in options) { writer.WriteLine(option); } writer.WriteLine("Assemblies in AssemblyFolders:"); foreach (var assemblyFolder in assemblyFolders) { writer.WriteLine("|- Folder: " + assemblyFolder); foreach (var assemblyOrDll in Directory.EnumerateFiles(assemblyFolder, "*.dll")) { var fileInfo = new FileInfo(assemblyOrDll); writer.WriteLine(" |- " + assemblyOrDll + " Size: " + fileInfo.Length + " Date: " + fileInfo.LastWriteTime); } } File.AppendAllText(debugLogFile, writer.ToString()); } catch { // ignored } } // Write current options to the response file var responseFile = Path.GetTempFileName(); File.WriteAllLines(responseFile, options); if (BurstLoader.IsDebugging) { Debug.Log($"bcl @{responseFile}\n\nResponse File:\n" + string.Join("\n", options)); } try { string generatedDebugInformationInOutput = ""; if ((report.summary.options & BuildOptions.Development) != 0) { generatedDebugInformationInOutput = GetOption(OptionDebug); } BclRunner.RunManagedProgram(Path.Combine(BurstLoader.RuntimePath, BurstAotCompilerExecutable), $"{generatedDebugInformationInOutput} \"@{responseFile}\"", new BclOutputErrorParser(), report); } catch (BuildFailedException) { throw; } catch (Exception e) { throw new BuildFailedException(e); } } }
private static void ExportGradle() { EditorUserBuildSettings.androidBuildSystem = AndroidBuildSystem.Gradle; EditorUserBuildSettings.exportAsGoogleAndroidProject = true; string path = PlayerPrefs.GetString("gradlePath", ""); path = string.IsNullOrEmpty(path) ? System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments) : path; path = EditorUtility.SaveFolderPanel("选择Gradle目录", path, ""); if (string.IsNullOrEmpty(path)) { return; } PlayerPrefs.SetString("gradlePath", path); PlayerPrefs.Save(); string assetsPath = path + "/src/main/assets".Replace("/", Path.AltDirectorySeparatorChar.ToString()); string newPath = path; bool hasProject = Directory.Exists(assetsPath); if (hasProject) { path.TrimEnd(Path.AltDirectorySeparatorChar); newPath = path.Substring(0, path.LastIndexOf(Path.AltDirectorySeparatorChar) + 1); newPath = newPath + Application.productName + "gradle"; if (Directory.Exists(newPath)) { Directory.Delete(newPath, true); } } Caching.ClearCache(); var error = BuildPipeline.BuildPlayer(GetBuildScenes(), newPath, BuildTarget.Android, BuildOptions.AcceptExternalModificationsToPlayer); //if (!string.IsNullOrEmpty(error)) //{ // Clear(); //} if (hasProject) { if (Directory.Exists(assetsPath)) { Directory.Delete(assetsPath, true); } Directory.Move(newPath + Path.AltDirectorySeparatorChar + Application.productName + "/src/main/assets".Replace("/", Path.AltDirectorySeparatorChar.ToString()), assetsPath); string cmd = path + Path.AltDirectorySeparatorChar + "gradlew"; ProcessStartInfo info = new ProcessStartInfo(cmd); info.WorkingDirectory = path; info.Arguments = "assembleRelease"; info.CreateNoWindow = false; info.ErrorDialog = true; info.UseShellExecute = true; if (info.UseShellExecute) { info.RedirectStandardOutput = false; info.RedirectStandardOutput = false; info.RedirectStandardError = false; info.RedirectStandardInput = false; } else { info.RedirectStandardOutput = true; info.RedirectStandardError = true; info.RedirectStandardInput = true; info.StandardOutputEncoding = UTF8Encoding.UTF8; info.StandardErrorEncoding = UTF8Encoding.UTF8; } Process process = Process.Start(info); if (!info.UseShellExecute) { //Debug.Log(process.StandardOutput); //Debug.Log(process.StandardError); } process.WaitForExit(); process.Close(); if (Application.platform == RuntimePlatform.WindowsEditor) { string openPath = Path.GetFullPath(path + "/build/outputs/apk/release/".Replace("/", Path.AltDirectorySeparatorChar.ToString())); Process.Start("explorer.exe", openPath); if (!string.IsNullOrEmpty(gitCommitID)) { Process pro = new Process(); pro.StartInfo.FileName = "cmd"; pro.StartInfo.CreateNoWindow = true; // 不创建新窗口 pro.StartInfo.UseShellExecute = false; //不启用shell启动进程 pro.StartInfo.RedirectStandardInput = true; // 重定向输入 pro.StartInfo.RedirectStandardOutput = true; // 重定向标准输出 pro.StartInfo.RedirectStandardError = false; //重定向标准错误 // 重定向错误输出 // pro.StartInfo.WorkingDirectory = Application.dataPath; //定义执行的路径 Console.OutputEncoding = Encoding.GetEncoding(936); pro.Start(); pro.StandardInput.AutoFlush = true; string gitlog = "git log --pretty=format:\"%s%n ========> %an , %ai%n\" {0}^..HEAD --grep \"·新增·\\|·修改·\\|·删除·\\|·其他·\" > {1}.log"; gitlog = string.Format(gitlog, gitCommitID.Trim(), openPath + DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")); pro.StandardInput.WriteLine(gitlog); //向cmd中输入命令 pro.StandardInput.WriteLine("exit"); //退出 string outRead = pro.StandardOutput.ReadToEnd(); //获得所有标准输出流 //Debug.Log(outRead); pro.WaitForExit(); //等待命令执行完成后退出 pro.Close(); //关闭窗口 } } } }
public static void BuildAllAssetBundles() { BuildPipeline.BuildAssetBundles("Assets/StreamingAssets/", BuildAssetBundleOptions.None, BuildTarget.StandaloneOSXUniversal); BuildPipeline.BuildAssetBundles("Assets/StreamingAssets/Android", BuildAssetBundleOptions.None, BuildTarget.Android); BuildPipeline.BuildAssetBundles("Assets/StreamingAssets/iOS", BuildAssetBundleOptions.None, BuildTarget.iOS); }
void StartBuild(string type) { // OneKeyBuild.DoOneKey(false); /*if (!UseAB) * { * EditorUtility.DisplayDialog("error", "正式包必须使用AB", "确定"); * return; * }*/ sbuilddir = sdir; if (!string.IsNullOrEmpty(targetBuildDir)) { sbuilddir = targetBuildDir + "/"; } if (!Directory.Exists(sbuilddir)) { Directory.CreateDirectory(sbuilddir); } #if UNITY_ANDROID && Cardboard string aarfilename = "gvr-permissionsupport-release.aar"; string aarpath = Application.dataPath + "/Plugins/Android/"; string aartopath = new DirectoryInfo(Application.dataPath).Parent.FullName + "/"; if (File.Exists(aarpath + aarfilename)) { if (File.Exists(aartopath + aarfilename)) { File.Delete(aartopath + aarfilename); } File.Move(aarpath + aarfilename, aartopath + aarfilename); AssetDatabase.Refresh(ImportAssetOptions.Default); } #endif string sbuildChannel = ""; string fullName = ""; fullName = PlayerSettings.applicationIdentifier + "." + sversion + "." + (bUsingIL2CPP ? "x64" : "x86"); string spath = sbuilddir + fullName; BuildTarget bt = BuildTarget.Android; #if UNITY_ANDROID spath += ".apk"; bt = BuildTarget.Android; #elif UNITY_IOS //ios needs a directory path rather than a file path; bt = BuildTarget.iOS; #elif UNITY_STANDALONE sbuilddir += "Game"; spath = sbuilddir; if (Directory.Exists(sbuilddir)) { Directory.Delete(sbuilddir, true); } Directory.CreateDirectory(sbuilddir); spath += "/Game.exe"; bt = BuildTarget.StandaloneWindows64; #else var defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(target); if (!string.IsNullOrEmpty(defines)) { var adef = defines.Replace(";", "."); spath += adef; } if (Directory.Exists(spath)) { Directory.Delete(spath, true); } if (File.Exists(spath + ".zip")) { File.Delete(spath + ".zip"); } Directory.CreateDirectory(spath); #endif LogWithTime(string.Format("Build to {0}", spath)); string sresult = ""; #if UNITY_2018 var r = BuildPipeline.BuildPlayer(FindEnabledEditorScenes(), spath, bt, BuildOptions.None); sresult = r.summary.result.ToString(); #else sresult = BuildPipeline.BuildPlayer(FindEnabledEditorScenes(), spath, bt, BuildOptions.None); #endif #if UNITY_IOS string projPath = PBXProject.GetPBXProjectPath(spath); PBXProject proj = new PBXProject(); proj.ReadFromFile(projPath); string targetGuid = proj.TargetGuidByName("Unity-iPhone"); proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libstdc++.tbd", "Frameworks/libstdc++.tbd", PBXSourceTree.Sdk)); proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libicucore.tbd", "Frameworks/libicucore.tbd", PBXSourceTree.Sdk)); proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libz.tbd", "Frameworks/libz.tbd", PBXSourceTree.Sdk)); proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libsqlite3.tbd", "Frameworks/libsqlite3.tbd", PBXSourceTree.Sdk)); proj.AddFileToBuild(targetGuid, proj.AddFile("usr/lib/libresolv.tbd", "Frameworks/libresolv.tbd", PBXSourceTree.Sdk)); proj.AddFrameworkToProject(targetGuid, "JavaScriptCore.framework", false); proj.AddFrameworkToProject(targetGuid, "MessageUI.framework", false); proj.AddFrameworkToProject(targetGuid, "AdSupport.framework", false); proj.AddFrameworkToProject(targetGuid, "VideoToolbox.framework", false); proj.AddFrameworkToProject(targetGuid, "CoreText.framework", false); proj.AddFrameworkToProject(targetGuid, "CoreTelephony.framework", false); proj.AddFrameworkToProject(targetGuid, "Accelerate.framework", false); proj.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "false"); proj.WriteToFile(projPath); PlistDocument plistDocument = new PlistDocument(); plistDocument.ReadFromFile(spath + "/Info.plist"); plistDocument.root.SetString("CFBundleDevelopmentRegion", "China"); plistDocument.root.SetString("MOBAppKey", "274fa9936816e"); plistDocument.root.SetString("MOBAppSecret", "8fa3f2e29924b70bd094b69cea3dd5ed"); PlistElementDict dict = plistDocument.root.AsDict(); dict.SetString("NSPhotoLibraryUsageDescription", photo); dict.SetString("NSCameraUsageDescription", "即将启用您的摄像头。"); dict.SetString("NSMicrophoneUsageDescription", "即将启用您的麦克风。"); /*PlistElementArray parray = plistDocument.root.CreateArray("CFBundleURLTypes"); * dict = parray.AddDict(); * dict.SetString("URL Schemes", "iqiyigame"); * dict.SetString("URL identifier", PlayerSettings.applicationIdentifier);*/ plistDocument.WriteToFile(spath + "/Info.plist"); #endif if (string.IsNullOrEmpty(sresult) || sresult == "Succeeded") { if (!string.IsNullOrEmpty(sBuildLog)) { LogWithTime(string.Format("BuildLog {0}:{1}", buildCode, sBuildLog)); sBuildLog = ""; } LogWithTime(string.Format("Build complete, {0} {1}({2})", spath, buildCode, buildCode)); buildCode = buildCode.Substring(0, buildCode.LastIndexOf(".") + 1) + (int.Parse(buildCode.Substring(buildCode.LastIndexOf(".") + 1)) + 1); #if UNITY_STANDALONE var pluginDir = Application.dataPath + "/Plugins/x64"; var destiPluginDir = sbuilddir + "/Game_Data/Plugins"; if (Directory.Exists(pluginDir)) { CopyDir(pluginDir, destiPluginDir); } BuildVersionFile(); #endif #if UNITY_IOS sbuilddir = spath; #endif System.Diagnostics.Process.Start(sbuilddir); } else { LogWithTime(string.Format("Build failed, {0}", sresult)); } }
static void BuildAllAssetBundles() { BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); }
public static AssetBundleManifest BuildAssetBundles(string a_outputPath, BuildAssetBundleOptions a_assetBundleOptions, BuildTarget a_targetPlatform) { AssetBundleManifest manifest; //Specific to our build machine //"$WORKSPACE/unity3d_editor.log" var workspace = System.Environment.GetEnvironmentVariable("WORKSPACE"); var editorLogFilePath = workspace + "/unity3d_editor.log"; if (!File.Exists(editorLogFilePath)) { editorLogFilePath = GetEditorLogFilePath(); if (!File.Exists(editorLogFilePath)) { Debug.LogWarning("Editor log file could not be found at: " + editorLogFilePath); return(BuildPipeline.BuildAssetBundles(a_outputPath, a_assetBundleOptions, a_targetPlatform)); } } var allAssetSizes = new Dictionary <string, long>(); var allAssetSizesPath = a_outputPath + "/assetSizes.tsv"; var deltaAssetSizes = new Dictionary <string, long>(); if (File.Exists(allAssetSizesPath)) { using (var allAssetSizesFile = new StreamReader(allAssetSizesPath)) { var assetLine = allAssetSizesFile.ReadLine(); while (assetLine != null) { var tokens = assetLine.Split('\t'); long bytes; if (long.TryParse(tokens[0], out bytes)) { allAssetSizes.Add(tokens[1], bytes); } assetLine = allAssetSizesFile.ReadLine(); } } } int bundleIndex = 0; using (var editorLog = new StreamReader(File.Open(editorLogFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) { editorLog.BaseStream.Seek(0, SeekOrigin.End); var manifestBefore = new Dictionary <string, System.DateTime>(); foreach (var manifestFile in Directory.GetFiles(a_outputPath, "*.manifest")) { var fileInfo = new FileInfo(manifestFile); manifestBefore.Add(manifestFile, fileInfo.LastWriteTime); } manifest = BuildPipeline.BuildAssetBundles(a_outputPath, a_assetBundleOptions, a_targetPlatform); var manifestsModified = new Dictionary <string, System.DateTime>(); foreach (var manifestFile in Directory.GetFiles(a_outputPath, "*.manifest")) { var fileInfo = new FileInfo(manifestFile); if (!manifestBefore.ContainsKey(manifestFile) || manifestBefore[manifestFile] != fileInfo.LastWriteTime) { manifestsModified.Add(manifestFile, fileInfo.LastWriteTime); } } var manifestsModifiedList = manifestsModified.OrderBy(a_item => a_item.Value); var section = BuildReportSection.Preamble; var bundleLogTempPath = FileUtil.GetUniqueTempPathInProject(); var bundleLog = new StreamWriter(bundleLogTempPath); var assetsTSVTempPath = FileUtil.GetUniqueTempPathInProject(); var assetsTSV = new StreamWriter(assetsTSVTempPath); var lastLog = new StreamWriter(a_outputPath + "/last.log"); // 3.9 kb 0.0% Assets/Standard Assets/Glass Refraction (Pro Only)/Sources/Shaders/Glass-Stained-BumpDistort.shader var assetSizeAndPath = new Regex(@"^ (\d+\.?\d*) (kb|mb)\t \d+\.?\d*\% ([^\0]+)"); while (true) { var logLine = editorLog.ReadLine(); if (logLine == null) { break; } lastLog.WriteLine(logLine); if (section == BuildReportSection.Preamble && logLine.StartsWith("Level ")) { section = BuildReportSection.Scenes; } else if ((section == BuildReportSection.Preamble || section == BuildReportSection.Scenes) && logLine.StartsWith("Textures ")) { section = BuildReportSection.SectionTotals; } else if (section == BuildReportSection.SectionTotals && logLine.StartsWith("Used Assets and files")) { section = BuildReportSection.AssetSizes; //Skip a line logLine = editorLog.ReadLine(); } else if (section == BuildReportSection.AssetSizes && string.IsNullOrEmpty(logLine)) { section = BuildReportSection.Preamble; bundleLog.Dispose(); assetsTSV.Dispose(); //Standalone bundle gets modified without changing manifest if (bundleIndex < manifestsModifiedList.Count()) { var manifestPath = manifestsModifiedList.ElementAt(bundleIndex).Key; FileReplace(bundleLogTempPath, Path.ChangeExtension(manifestPath, ".log")); FileReplace(assetsTSVTempPath, Path.ChangeExtension(manifestPath, ".tsv")); //open new temp files bundleIndex++; bundleLogTempPath = FileUtil.GetUniqueTempPathInProject(); bundleLog = new StreamWriter(bundleLogTempPath); assetsTSVTempPath = FileUtil.GetUniqueTempPathInProject(); assetsTSV = new StreamWriter(assetsTSVTempPath); } } if (section == BuildReportSection.Scenes || section == BuildReportSection.SectionTotals || section == BuildReportSection.AssetSizes) { bundleLog.WriteLine(logLine); } if (section == BuildReportSection.Scenes) { } if (section == BuildReportSection.AssetSizes) { var match = assetSizeAndPath.Match(logLine); if (match.Success && match.Groups.Count == 4) { var assetPath = match.Groups[3].Value; var fractionalSizeString = match.Groups[1].Value; var sizeUnitsString = match.Groups[2].Value; double fractionalSize; if (double.TryParse(fractionalSizeString, out fractionalSize)) { long bytes; if (string.Compare(sizeUnitsString, "mb") == 0) { bytes = (long)(fractionalSize * 1024 * 1024); } else //if(string.Compare(sizeUnitsString,"kb") == 0) { bytes = (long)(fractionalSize * 1024); } assetsTSV.WriteLine(bytes + "\t" + assetPath); long previousSize; if (allAssetSizes.TryGetValue(assetPath, out previousSize)) { if (previousSize == bytes) { continue; } allAssetSizes[assetPath] = bytes; deltaAssetSizes[assetPath] = bytes - previousSize; } else { allAssetSizes[assetPath] = bytes; } } } } } bundleLog.Dispose(); assetsTSV.Dispose(); lastLog.Dispose(); } using (var allAssetSizesFile = new StreamWriter(allAssetSizesPath)) { foreach (var allAssetSize in allAssetSizes.OrderByDescending(a_v => a_v.Value).ToList()) { allAssetSizesFile.WriteLine(allAssetSize.Value + "\t" + allAssetSize.Key); } } var deltaAssetSizesPath = a_outputPath + "/assetSizesDelta.tsv"; using (var allAssetDeltaSizesFile = new StreamWriter(deltaAssetSizesPath)) { foreach (var allAssetSize in deltaAssetSizes.OrderByDescending(a_v => a_v.Value).ToList()) { allAssetDeltaSizesFile.WriteLine(allAssetSize.Value + "\t" + allAssetSize.Key); } } return(manifest); }