public static void ReLinkBuiltStreamingAssetsFolder(BuildTarget target) { string path = ""; if (target.ToString().ToLowerInvariant().StartsWith("standalone")) { path = Path.Combine(OUTPUT_BUILT_AB_ROOT, "PC"); } else { path = Path.Combine(OUTPUT_BUILT_AB_ROOT, BuildTargetUtility.TargetToHumaneString(target)); } RemoveSymbolicLinkToBuiltStreamingAssetsFolder(); if (Directory.Exists(path)) { try { if (SymbolicLinkTool.CreateSymbolicLinkBetweenFolders(LOCAL_STREAMING_AB_ROOT, path)) { AssetDatabase.Refresh(); } } catch (System.Exception e) { Debug.LogException(e); } } else { Debug.LogWarning("cannot found SAAB folder for platform(" + target + ")."); } }
public static void SwitchPlatform() { try { var arguments = new List <string>(System.Environment.GetCommandLineArgs()); BuildTarget target = EditorUserBuildSettings.activeBuildTarget; int targetIndex = arguments.FindIndex(a => a == "-target"); if (targetIndex >= 0) { var targetStr = arguments[targetIndex + 1]; var newTarget = (BuildTarget)Enum.Parse(typeof(BuildTarget), targetStr); //var newTarget = BuildTargetUtility.BuildTargetFromString(arguments[targetIndex + 1]); if (newTarget != target) { #if UNITY_5_6 || UNITY_5_6_OR_NEWER EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetUtility.TargetToGroup(newTarget), newTarget); #else EditorUserBuildSettings.SwitchActiveBuildTarget(newTarget); #endif target = newTarget; } } } catch (Exception ex) { Debug.Log("switch platform fail"); } }
private string PrepareOutputDirectory(BuildTarget target, Model.NodeData node, bool throwException) { var outputOption = (SaveBundlesConfigurationNode.OutputOption)_inputOption[target]; if (outputOption == SaveBundlesConfigurationNode.OutputOption.BuildInCacheDirectory) { return(FileUtility.EnsureWorkingCacheDirExists(target, node, "BundlesConfiguration")); } var outputDir = _inputDir[target]; outputDir = outputDir.Replace("{Platform}", BuildTargetUtility.TargetToAssetBundlePlatformName(target)); if (throwException) { if (string.IsNullOrEmpty(outputDir)) { throw new NodeException("Output directory is empty.", "Select valid output directory from inspector.", node); } if (target != BuildTargetUtility.GroupToTarget(BuildTargetGroup.Unknown) && outputOption == SaveBundlesConfigurationNode.OutputOption.ErrorIfNoOutputDirectoryFound) { if (!Directory.Exists(outputDir)) { throw new NodeException("Output directory not found.", "Create output directory or select other valid directory from inspector.", node); } } } return(outputDir); }
private string PrepareOutputDirectory(BuildTarget target, Model.NodeData node) { var outputOption = (OutputOption)_outputOption[target]; if (outputOption == OutputOption.BuildInCacheDirectory) { return(FileUtility.EnsureWorkingCacheDirExists(target, node, "")); } if (outputOption == OutputOption.BuildInBundlesCacheDirectory) { return(FileUtility.EnsureAssetBundleCacheDirExists(target, node)); } var outputDir = _outputDir[target]; outputDir = outputDir.Replace("{Platform}", BuildTargetUtility.TargetToAssetBundlePlatformName(target)); return(outputDir); }
public override void OnInspectorGUI(NodeGUI node, AssetReferenceStreamManager streamManager, NodeGUIEditor editor, Action onValueChanged) { if (_enabledOptions == null) { return; } EditorGUILayout.HelpBox("Удаляет папку и все файлы в ней", MessageType.Info); editor.UpdateNodeName(node); GUILayout.Space(10f); //Show target configuration tab editor.DrawPlatformSelector(node); using (new EditorGUILayout.VerticalScope(GUI.skin.box)) { var disabledScope = editor.DrawOverrideTargetToggle(node, _enabledOptions.ContainsValueOf(editor.CurrentEditingGroup), (bool enabled) => { using (new RecordUndoScope("Remove Target Bundle Options", node, true)) { if (enabled) { _enabledOptions[editor.CurrentEditingGroup] = _enabledOptions.DefaultValue; _outputDir[editor.CurrentEditingGroup] = _outputDir.DefaultValue; _outputOption[editor.CurrentEditingGroup] = _outputOption.DefaultValue; } else { _enabledOptions.Remove(editor.CurrentEditingGroup); _outputDir.Remove(editor.CurrentEditingGroup); _outputOption.Remove(editor.CurrentEditingGroup); } onValueChanged(); } }); using (disabledScope) { OutputOption opt = (OutputOption)_outputOption[editor.CurrentEditingGroup]; var newOption = (OutputOption)EditorGUILayout.EnumPopup("Output Option", opt); if (newOption != opt) { using (new RecordUndoScope("Change Output Option", node, true)) { _outputOption[editor.CurrentEditingGroup] = (int)newOption; onValueChanged(); } } using (new EditorGUI.DisabledScope(opt == OutputOption.BuildInCacheDirectory || opt == OutputOption.BuildInBundlesCacheDirectory)) { var newDirPath = editor.DrawFolderSelector("Output Directory", "Select Output Folder", _outputDir[editor.CurrentEditingGroup], Application.dataPath + "/../", (string folderSelected) => { var projectPath = Directory.GetParent(Application.dataPath).ToString(); if (projectPath == folderSelected) { folderSelected = string.Empty; } else { var index = folderSelected.IndexOf(projectPath); if (index >= 0) { folderSelected = folderSelected.Substring(projectPath.Length + index); if (folderSelected.IndexOf('/') == 0) { folderSelected = folderSelected.Substring(1); } } } return(folderSelected); } ); if (newDirPath != _outputDir[editor.CurrentEditingGroup]) { using (new RecordUndoScope("Change Output Directory", node, true)) { _outputDir[editor.CurrentEditingGroup] = newDirPath; onValueChanged(); } } var outputDir = PrepareOutputDirectory(BuildTargetUtility.GroupToTarget(editor.CurrentEditingGroup), node.Data); using (new EditorGUI.DisabledScope(!Directory.Exists(outputDir))) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); #if UNITY_EDITOR_OSX string buttonName = "Reveal in Finder"; #else string buttonName = "Show in Explorer"; #endif if (GUILayout.Button(buttonName)) { EditorUtility.RevealInFinder(outputDir); } } } EditorGUILayout.HelpBox("You can use '{Platform}' variable for Output Directory path to include platform name.", MessageType.Info); } } } }
/* * DoPostprocess() is called when build performed. * @param [in] reports collection of AssetBundleBuildReport from each BundleBuilders. */ public void DoPostprocess(IEnumerable <AssetBundleBuildReport> buildReports, IEnumerable <ExportReport> exportReports) { // リスト名とversionから、出力するlistの名称を決め、ファイルを移動させる。 // なんらか対象の設定の把握ができるといいんだけど、exportPathからとるか。 var sampleExportArray = exportReports.ToArray(); if (sampleExportArray == null || sampleExportArray.Length == 0) { // no exports found. return; } // pick first exporter only. if (!sampleExportArray[0].ExportedItems.Any()) { // empty exports. return; } Debug.Log("sampleExport destination:" + sampleExportArray[0].ExportedItems[0].destination); Debug.Log("currentTargetPlatform:" + EditorUserBuildSettings.activeBuildTarget + " export platform str is:" + BuildTargetUtility.TargetToAssetBundlePlatformName(EditorUserBuildSettings.activeBuildTarget)); /* * ここは大変まどろっこしいことをしていて、 * exporterからexportPathを取得できないので、exportされたAssetから"現在のプラットフォームString/現在のプラットフォームString" というパス/ファイル名になるmanifestファイルを探し出し、 * そのパスの直上のディレクトリ名がexportPathの最下位のフォルダ名になるので、それを取得しリスト名として使用している。 */ var exportPlatformStr = BuildTargetUtility.TargetToAssetBundlePlatformName(EditorUserBuildSettings.activeBuildTarget); var platformDelimiter = exportPlatformStr + "/" + exportPlatformStr + ".manifest";// XPlatform/XPlatform.manifest var rootManifestEntry = sampleExportArray[0].ExportedItems.Where(p => p.destination.Contains(platformDelimiter)).FirstOrDefault(); if (rootManifestEntry == null) { Debug.Log("no exported root manifest with :" + platformDelimiter + " found."); ///もしここに来ているようなら、何かAssetGraphToolsの設定間違えの可能性があります。 ///元から入っているmain_assetsのAssetGraphToolの設定を見てください。 return; } var wholeExportFolderName = rootManifestEntry.destination.Substring(0, rootManifestEntry.destination.IndexOf(platformDelimiter) - 1 /*remove last / */); var settingFilePath = wholeExportFolderName + ".json"; if (!File.Exists(settingFilePath)) { Debug.Log("no setting file exists:" + settingFilePath); return; } var settingFileData = File.ReadAllBytes(settingFilePath); if (settingFileData.Length == 0) { Debug.Log("setting file is empty:" + settingFilePath + " need to define ListProfile class parameters."); return; } var settingProfile = JsonUtility.FromJson <ListProfile>(Encoding.UTF8.GetString(settingFileData)); var listIdentity = settingProfile.identity; var listVersion = settingProfile.version; var rootManifestPath = rootManifestEntry.destination; Debug.Log("generating AssetBundleList. rootManifestPath:" + rootManifestPath + " generate list identity:" + listIdentity + " version:" + listVersion); var targetDirectory = FileController.PathCombine(wholeExportFolderName, exportPlatformStr, listVersion); // check if version folder is exists. if (Directory.Exists(targetDirectory)) { Debug.Log("same version files are already exists. list identity:" + listIdentity + " version:" + listVersion + " path:" + targetDirectory + " need to delete directory."); return; // Directory.Delete(targetDirectory, true); } // create version directory under exportPlatformStr. // then copy necessary files. { Directory.CreateDirectory(targetDirectory); foreach (var exportReport in exportReports) { var items = exportReport.ExportedItems; foreach (var item in items) { var currentPath = item.destination; // skip root manifest and root file. if (currentPath.Contains(exportPlatformStr + "/" + exportPlatformStr)) { continue; } var fileName = Path.GetFileName(currentPath); if (fileName == listIdentity + ".json") { throw new Exception("generated AssetBundle name:" + listIdentity + ".json is overlapped with list name. please change assetBundle name, extension or list identity."); } var dirPath = Path.GetDirectoryName(currentPath); var destPath = FileController.PathCombine(dirPath, listVersion, fileName); File.Copy(currentPath, destPath); } } } // root manifest から全てのbundleの依存関係を取り出す + 各bundleのManifestから詳細を取得する。 { var bundleAndDependencies = new List <AssetBundleInfo>(); /* * load root manifest file and get assetBundle names and dependencies. */ using (var sr = new StreamReader(rootManifestPath)) { // read root manifest file. { var rootYaml = new YamlStream(); rootYaml.Load(sr); var rootMapping = (YamlMappingNode)rootYaml.Documents[0].RootNode; foreach (var root_item in rootMapping) { var rootKey = ((YamlScalarNode)root_item.Key).Value; switch (rootKey) { case "ManifestFileVersion": { // Debug.LogError("ManifestFileVersion:" + ((YamlScalarNode)root_item.Value).Value); break; } case "AssetBundleManifest": { var assetBundleManifestMapping = (YamlMappingNode)root_item.Value; foreach (var assetBundleManifestMapping_item in assetBundleManifestMapping) { var manifestKey = ((YamlScalarNode)assetBundleManifestMapping_item.Key).Value; switch (manifestKey) { case "AssetBundleInfos": { var manifestInfoSeq = (YamlMappingNode)assetBundleManifestMapping_item.Value; foreach (var manifestInfo_item in manifestInfoSeq) { var bundleInfo = new AssetBundleInfo(); var bundleInfoMapping = (YamlMappingNode)manifestInfo_item.Value; foreach (var info_item in bundleInfoMapping) { var infoKey = ((YamlScalarNode)info_item.Key).Value; switch (infoKey) { case "Name": { var name = ((YamlScalarNode)info_item.Value).Value; // Debug.LogError("name:" + name); bundleInfo.bundleName = name; break; } case "Dependencies": { var dependenciesMapping = (YamlMappingNode)info_item.Value; foreach (var dependency_item in dependenciesMapping) { var dependentBundleName = ((YamlScalarNode)dependency_item.Value).Value; // Debug.LogError("dependentBundleName:" + dependentBundleName); } var dependentBundleNames = dependenciesMapping.Select(t => ((YamlScalarNode)t.Value).Value).ToArray(); bundleInfo.dependsBundleNames = dependentBundleNames; break; } } } bundleAndDependencies.Add(bundleInfo); } break; } } } break; } } } } } // create assetBundleList. var assetBundleInfos = new List <AssetBundleInfo>(); /* * load each assetBundle info from bundle manifests. */ foreach (var bundleAndDependencie in bundleAndDependencies) { var targetBundleName = bundleAndDependencie.bundleName; var newAssetBundleInfo = new AssetBundleInfo(); newAssetBundleInfo.bundleName = targetBundleName; newAssetBundleInfo.dependsBundleNames = bundleAndDependencie.dependsBundleNames; using (var sr = new StreamReader(FileController.PathCombine(wholeExportFolderName, exportPlatformStr, targetBundleName + ".manifest"))) { var rootYaml = new YamlStream(); rootYaml.Load(sr); var rootMapping = (YamlMappingNode)rootYaml.Documents[0].RootNode; foreach (var root_item in rootMapping) { var rootKey = ((YamlScalarNode)root_item.Key).Value; switch (rootKey) { case "CRC": { var crc = Convert.ToUInt32(((YamlScalarNode)root_item.Value).Value); // Debug.LogError("crc:" + crc); newAssetBundleInfo.crc = crc; break; } case "Assets": { var assetNamesSeq = (YamlSequenceNode)root_item.Value; var assetNames = assetNamesSeq.Select(n => ((YamlScalarNode)n).Value).ToArray(); // foreach (var assetName in assetNames) { // Debug.LogError("assetName:" + assetName); // } newAssetBundleInfo.assetNames = assetNames; break; } case "Hashes": { var hashMapping = (YamlMappingNode)root_item.Value; foreach (var hash_item in hashMapping) { var hashKey = ((YamlScalarNode)hash_item.Key).Value; switch (hashKey) { case "AssetFileHash": { var assetHashMapping = (YamlMappingNode)hash_item.Value; foreach (var assetHash_item in assetHashMapping) { var assetHashKey = ((YamlScalarNode)assetHash_item.Key).Value; switch (assetHashKey) { case "Hash": { var hashStr = ((YamlScalarNode)assetHash_item.Value).Value; // Debug.LogError("hashStr:" + hashStr); newAssetBundleInfo.hash = hashStr; break; } } } break; } } } break; } } } // set size. newAssetBundleInfo.size = new FileInfo(FileController.PathCombine(wholeExportFolderName, exportPlatformStr, targetBundleName)).Length; // Debug.LogError("newAssetBundleInfo.size:" + newAssetBundleInfo.size); assetBundleInfos.Add(newAssetBundleInfo); } } var assetBundleList = new AssetBundleList(listIdentity, exportPlatformStr, listVersion, assetBundleInfos.ToArray()); var str = JsonUtility.ToJson(assetBundleList, true); var listOutputPaht = FileController.PathCombine(wholeExportFolderName, exportPlatformStr, listVersion, listIdentity + ".json"); using (var sw = new StreamWriter(listOutputPaht)) { sw.WriteLine(str); } } }
/* * DoPostprocess() is called when build performed. * @param [in] reports collection of AssetBundleBuildReport from each BundleBuilders. */ public void DoPostprocess(IEnumerable <AssetBundleBuildReport> buildReports, IEnumerable <ExportReport> exportReports) { // リスト名とversionから、出力するlistの名称を決め、ファイルを移動させる。 // なんらか対象の設定の把握ができるといいんだけど、exportPathからとるか。 var sampleExportArray = exportReports.ToArray(); if (sampleExportArray == null || sampleExportArray.Length == 0) { // no exports found. return; } // pick first exporter only. if (!sampleExportArray[0].ExportedItems.Any()) { // empty exports. return; } var exportPlatformStr = BuildTargetUtility.TargetToAssetBundlePlatformName(EditorUserBuildSettings.activeBuildTarget); var platformDelimiter = exportPlatformStr + "/" + exportPlatformStr + ".manifest";// XPlatform/XPlatform.manifest var rootManifestEntry = sampleExportArray[0].ExportedItems.Where(p => p.destination.Contains(platformDelimiter)).FirstOrDefault(); if (rootManifestEntry == null) { Debug.Log("no exported root manifest with :" + platformDelimiter + " found."); return; } // full path for export base path. var wholeExportFolderPath = rootManifestEntry.destination.Substring(0, rootManifestEntry.destination.IndexOf(platformDelimiter) - 1 /*remove last / */); var graphName = new DirectoryInfo(wholeExportFolderPath).Name; var settingFilePath = EditVersionJson(graphName); var settingFileData = string.Empty; using (var sr = new StreamReader(settingFilePath)) { settingFileData = sr.ReadToEnd(); } var settingProfile = JsonUtility.FromJson <ListProfile>(settingFileData); var listIdentity = settingProfile.identity; var listVersion = settingProfile.version; var rootManifestPath = rootManifestEntry.destination; Debug.Log("generating AssetBundleList. rootManifestPath:" + rootManifestPath + " generate list identity:" + listIdentity + " version:" + listVersion); var targetDirectory = FileController.PathCombine(wholeExportFolderPath, exportPlatformStr, listVersion); // check if version folder is exists. if (Directory.Exists(targetDirectory)) { Debug.Log("same version files are already exists. list identity:" + listIdentity + " version:" + listVersion + " path:" + targetDirectory + " need to delete directory or modify list version. for editing list version, open Window > Autoya > Open AssetBundleListVersionEditor. "); return; } // create version directory under exportPlatformStr. // then copy necessary files. { Directory.CreateDirectory(targetDirectory); foreach (var exportReport in exportReports) { var items = exportReport.ExportedItems; foreach (var item in items) { var currentPath = item.destination; // skip root manifest and root file. if (currentPath.Contains(exportPlatformStr + "/" + exportPlatformStr)) { continue; } // skip manifest file. if (currentPath.EndsWith(".manifest")) { continue; } var fileName = Path.GetFileName(currentPath); if (fileName == listIdentity + ".json") { throw new Exception("generated AssetBundle name:" + listIdentity + ".json is overlapped with list name. please change assetBundle name, extension or list identity."); } var dirPath = Path.GetDirectoryName(currentPath); var destPath = FileController.PathCombine(dirPath, listVersion, fileName); File.Copy(currentPath, destPath); } } } // root manifest から全てのbundleの依存関係を取り出す + 各bundleのManifestから詳細を取得する。 { var bundleAndDependencies = new List <AssetBundleInfo>(); /* * load root manifest file and get assetBundle names and dependencies. */ using (var sr = new StreamReader(rootManifestPath)) { // read root manifest file. { var rootYaml = new YamlStream(); rootYaml.Load(sr); var rootMapping = (YamlMappingNode)rootYaml.Documents[0].RootNode; foreach (var root_item in rootMapping) { var rootKey = ((YamlScalarNode)root_item.Key).Value; switch (rootKey) { case "ManifestFileVersion": { // Debug.LogError("ManifestFileVersion:" + ((YamlScalarNode)root_item.Value).Value); break; } case "AssetBundleManifest": { var assetBundleManifestMapping = (YamlMappingNode)root_item.Value; foreach (var assetBundleManifestMapping_item in assetBundleManifestMapping) { var manifestKey = ((YamlScalarNode)assetBundleManifestMapping_item.Key).Value; switch (manifestKey) { case "AssetBundleInfos": { var manifestInfoSeq = (YamlMappingNode)assetBundleManifestMapping_item.Value; foreach (var manifestInfo_item in manifestInfoSeq) { var bundleInfo = new AssetBundleInfo(); var bundleInfoMapping = (YamlMappingNode)manifestInfo_item.Value; foreach (var info_item in bundleInfoMapping) { var infoKey = ((YamlScalarNode)info_item.Key).Value; switch (infoKey) { case "Name": { var name = ((YamlScalarNode)info_item.Value).Value; // Debug.LogError("name:" + name); bundleInfo.bundleName = name; break; } case "Dependencies": { var dependenciesMapping = (YamlMappingNode)info_item.Value; foreach (var dependency_item in dependenciesMapping) { var dependentBundleName = ((YamlScalarNode)dependency_item.Value).Value; // Debug.LogError("dependentBundleName:" + dependentBundleName); } var dependentBundleNames = dependenciesMapping.Select(t => ((YamlScalarNode)t.Value).Value).ToArray(); bundleInfo.dependsBundleNames = dependentBundleNames; break; } } } bundleAndDependencies.Add(bundleInfo); } break; } } } break; } } } } } // create assetBundleList. var assetBundleInfos = new List <AssetBundleInfo>(); var classIdSet = new HashSet <int>(); /* * load each assetBundle info from bundle manifests. */ foreach (var bundleAndDependencie in bundleAndDependencies) { var targetBundleName = bundleAndDependencie.bundleName; var newAssetBundleInfo = new AssetBundleInfo(); newAssetBundleInfo.bundleName = targetBundleName; newAssetBundleInfo.dependsBundleNames = bundleAndDependencie.dependsBundleNames; using (var sr = new StreamReader(FileController.PathCombine(wholeExportFolderPath, exportPlatformStr, targetBundleName + ".manifest"))) { var rootYaml = new YamlStream(); rootYaml.Load(sr); var rootMapping = (YamlMappingNode)rootYaml.Documents[0].RootNode; foreach (var root_item in rootMapping) { var rootKey = ((YamlScalarNode)root_item.Key).Value; switch (rootKey) { case "CRC": { var crc = Convert.ToUInt32(((YamlScalarNode)root_item.Value).Value); // Debug.LogError("crc:" + crc); newAssetBundleInfo.crc = crc; break; } case "Assets": { var assetNamesSeq = (YamlSequenceNode)root_item.Value; var assetNames = assetNamesSeq.Select(n => ((YamlScalarNode)n).Value).ToArray(); // foreach (var assetName in assetNames) { // Debug.LogError("assetName:" + assetName); // } newAssetBundleInfo.assetNames = assetNames; break; } case "Hashes": { var hashMapping = (YamlMappingNode)root_item.Value; foreach (var hash_item in hashMapping) { var hashKey = ((YamlScalarNode)hash_item.Key).Value; switch (hashKey) { case "AssetFileHash": { var assetHashMapping = (YamlMappingNode)hash_item.Value; foreach (var assetHash_item in assetHashMapping) { var assetHashKey = ((YamlScalarNode)assetHash_item.Key).Value; switch (assetHashKey) { case "Hash": { var hashStr = ((YamlScalarNode)assetHash_item.Value).Value; // Debug.LogError("hashStr:" + hashStr); newAssetBundleInfo.hash = hashStr; break; } } } break; } } } break; } case "ClassTypes": { var seq = (YamlSequenceNode)root_item.Value; foreach (var iSeq in seq) { var innerMap = (YamlMappingNode)iSeq; foreach (var map in innerMap) { switch ((string)map.Key) { case "Class": { classIdSet.Add(Convert.ToInt32((string)map.Value)); break; } } } } break; } default: { // ignore. break; } } } // set size. newAssetBundleInfo.size = new FileInfo(FileController.PathCombine(wholeExportFolderPath, exportPlatformStr, targetBundleName)).Length; // Debug.LogError("newAssetBundleInfo.size:" + newAssetBundleInfo.size); assetBundleInfos.Add(newAssetBundleInfo); } } var assetBundleList = new AssetBundleList(listIdentity, exportPlatformStr, listVersion, assetBundleInfos.ToArray()); var str = JsonUtility.ToJson(assetBundleList, true); var listOutputPath = FileController.PathCombine(wholeExportFolderPath, exportPlatformStr, listVersion, listIdentity + ".json"); using (var sw = new StreamWriter(listOutputPath)) { sw.WriteLine(str); } // generate Link.xml LinkXMLGenerator.ExportLinkXMLWithUsingClassIds(Application.dataPath, classIdSet.ToArray()); } }
public override void OnInspectorGUI(NodeGUI node, AssetReferenceStreamManager streamManager, NodeGUIEditor editor, Action onValueChanged) { if (_enabledOptions == null) { return; } EditorGUILayout.HelpBox("Сохраняет конфигурацию бандлей в json", MessageType.Info); editor.UpdateNodeName(node); GUILayout.Space(10f); //Show target configuration tab editor.DrawPlatformSelector(node); using (new EditorGUILayout.VerticalScope(GUI.skin.box)) { var disabledScope = editor.DrawOverrideTargetToggle(node, _enabledOptions.ContainsValueOf(editor.CurrentEditingGroup), (bool enabled) => { using (new RecordUndoScope("Remove Target Bundle Options", node, true)) { if (enabled) { _enabledOptions[editor.CurrentEditingGroup] = _enabledOptions.DefaultValue; _inputDir[editor.CurrentEditingGroup] = _inputDir.DefaultValue; _inputOption[editor.CurrentEditingGroup] = _inputOption.DefaultValue; _fileName[editor.CurrentEditingGroup] = _fileName.DefaultValue; } else { _enabledOptions.Remove(editor.CurrentEditingGroup); _inputDir.Remove(editor.CurrentEditingGroup); _inputOption.Remove(editor.CurrentEditingGroup); _fileName.Remove(editor.CurrentEditingGroup); } onValueChanged(); } }); using (disabledScope) { SaveBundlesConfigurationNode.OutputOption opt = (SaveBundlesConfigurationNode.OutputOption)_inputOption[editor.CurrentEditingGroup]; var newOption = (SaveBundlesConfigurationNode.OutputOption)EditorGUILayout.EnumPopup("Output Option", opt); if (newOption != opt) { using (new RecordUndoScope("Change Output Option", node, true)) { _inputOption[editor.CurrentEditingGroup] = (int)newOption; onValueChanged(); } } using (new EditorGUI.DisabledScope(opt == SaveBundlesConfigurationNode.OutputOption.BuildInCacheDirectory)) { var newDirPath = editor.DrawFolderSelector("Output Directory", "Select Output Folder", _inputDir[editor.CurrentEditingGroup], Application.dataPath + "/../", (string folderSelected) => { var projectPath = Directory.GetParent(Application.dataPath).ToString(); if (projectPath == folderSelected) { folderSelected = string.Empty; } else { var index = folderSelected.IndexOf(projectPath); if (index >= 0) { folderSelected = folderSelected.Substring(projectPath.Length + index); if (folderSelected.IndexOf('/') == 0) { folderSelected = folderSelected.Substring(1); } } } return(folderSelected); } ); if (newDirPath != _inputDir[editor.CurrentEditingGroup]) { using (new RecordUndoScope("Change Output Directory", node, true)) { _inputDir[editor.CurrentEditingGroup] = newDirPath; onValueChanged(); } } var outputDir = PrepareOutputDirectory(BuildTargetUtility.GroupToTarget(editor.CurrentEditingGroup), node.Data, false); if (opt == SaveBundlesConfigurationNode.OutputOption.ErrorIfNoOutputDirectoryFound && editor.CurrentEditingGroup != BuildTargetGroup.Unknown && !string.IsNullOrEmpty(_inputDir[editor.CurrentEditingGroup]) && !Directory.Exists(outputDir)) { using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField(outputDir + " does not exist."); if (GUILayout.Button("Create directory")) { Directory.CreateDirectory(outputDir); } } EditorGUILayout.Space(); string parentDir = Path.GetDirectoryName(_inputDir[editor.CurrentEditingGroup]); if (Directory.Exists(parentDir)) { EditorGUILayout.LabelField("Available Directories:"); string[] dirs = Directory.GetDirectories(parentDir); foreach (string s in dirs) { EditorGUILayout.LabelField(s); } } EditorGUILayout.Space(); } using (new EditorGUI.DisabledScope(!Directory.Exists(outputDir))) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); #if UNITY_EDITOR_OSX string buttonName = "Reveal in Finder"; #else string buttonName = "Show in Explorer"; #endif if (GUILayout.Button(buttonName)) { EditorUtility.RevealInFinder(outputDir); } } } EditorGUILayout.HelpBox("You can use '{Platform}' variable for Output Directory path to include platform name.", MessageType.Info); } GUILayout.Space(8f); var fileName = _fileName[editor.CurrentEditingGroup]; var newFileName = EditorGUILayout.TextField("File Name", fileName); if (newFileName != fileName) { using (new RecordUndoScope("Change File Name", node, true)) { _fileName[editor.CurrentEditingGroup] = newFileName; onValueChanged(); } } } } }