public static void RemoveBundleSettings(string nodePath) { EditorUtility.DisplayProgressBar("AssetBundleGraph unbundlize all resources...", nodePath, 0); var filePathsInFolder = FileUtility.FilePathsInFolder(nodePath); foreach (var filePath in filePathsInFolder) { if (FileUtility.IsMetaFile(filePath)) { continue; } if (FileUtility.ContainsHiddenFiles(filePath)) { continue; } var assetImporter = AssetImporter.GetAtPath(filePath); // assetImporter is null when the asset is not accepted by Unity. // e.g. file.my_new_extension is ignored by Unity. if (assetImporter == null) { continue; } if (assetImporter.GetType() == typeof(UnityEditor.MonoImporter)) { continue; } assetImporter.assetBundleName = string.Empty; } EditorUtility.ClearProgressBar(); }
public void Run(string nodeName, string nodeId, string connectionIdToNextNode, Dictionary <string, List <Asset> > unused, List <string> alreadyCached, Action <string, string, Dictionary <string, List <Asset> >, List <string> > Output) { ValidateLoadPath( loadFilePath, loadFilePath, () => { //throw new AssetBundleGraphBuildException(nodeName + ": Load Path is empty."); }, () => { throw new AssetBundleGraphBuildException(nodeName + ": Directory not found: " + loadFilePath); } ); // SOMEWHERE_FULLPATH/PROJECT_FOLDER/Assets/ var assetsFolderPath = Application.dataPath + AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR; var outputSource = new List <Asset>(); try { var targetFilePaths = FileUtility.FilePathsInFolder(loadFilePath); foreach (var targetFilePath in targetFilePaths) { if (targetFilePath.Contains(AssetBundleGraphSettings.ASSETBUNDLEGRAPH_PATH)) { continue; } // already contained into Assets/ folder. // imported path is Assets/SOMEWHERE_FILE_EXISTS. if (targetFilePath.StartsWith(assetsFolderPath)) { var importFrom = targetFilePath.Replace(assetsFolderPath, AssetBundleGraphSettings.ASSETS_PATH); outputSource.Add(Asset.CreateNewAssetFromLoader(targetFilePath, importFrom)); continue; } throw new AssetBundleGraphSetupException(nodeName + ": Invalid target file path. Path needs to be set under Assets/ :" + targetFilePath); } var outputDir = new Dictionary <string, List <Asset> > { { "0", outputSource } }; Output(nodeId, connectionIdToNextNode, outputDir, new List <string>()); } catch (Exception e) { throw new NodeException(e.Message, nodeId); } }
public void Run(string nodeName, string nodeId, string connectionIdToNextNode, Dictionary <string, List <Asset> > groupedSources, List <string> alreadyCached, Action <string, string, Dictionary <string, List <Asset> >, List <string> > Output) { var usedCache = new List <string>(); var invalids = new List <string>(); foreach (var sources in groupedSources.Values) { foreach (var source in sources) { if (string.IsNullOrEmpty(source.importFrom)) { invalids.Add(source.absoluteAssetPath); } } } if (invalids.Any()) { throw new NodeException(string.Join(", ", invalids.ToArray()) + " are not imported yet. These assets need to be imported before prefabricated.", nodeId); } var recommendedPrefabOutputDirectoryPath = FileUtility.PathCombine(AssetBundleGraphSettings.PREFABRICATOR_CACHE_PLACE, nodeId, SystemDataUtility.GetCurrentPlatformKey()); var outputDict = new Dictionary <string, List <Asset> >(); var cachedOrGenerated = new List <string>(); foreach (var groupKey in groupedSources.Keys) { var inputSources = groupedSources[groupKey]; var recommendedPrefabPath = FileUtility.PathCombine(recommendedPrefabOutputDirectoryPath, groupKey); if (!recommendedPrefabPath.EndsWith(AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR.ToString())) { recommendedPrefabPath = recommendedPrefabPath + AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR.ToString(); } /* * ready input resource info for execute. not contains cache in this node. */ var assets = new List <DepreacatedAssetInfo>(); foreach (var assetData in inputSources) { var assetName = assetData.fileNameAndExtension; var assetType = assetData.assetType; var assetPath = assetData.importFrom; var assetDatabaseId = assetData.assetDatabaseId; assets.Add(new DepreacatedAssetInfo(assetName, assetType, assetPath, assetDatabaseId)); } // collect generated prefab path. var generated = new List <string>(); var outputSources = new List <Asset>(); /* * Prefabricate(GameObject baseObject, string prefabName, bool forceGenerate) method. */ Func <GameObject, string, bool, string> Prefabricate = (GameObject baseObject, string prefabName, bool forceGenerate) => { var newPrefabOutputPath = Path.Combine(recommendedPrefabPath, prefabName); if (forceGenerate || !SystemDataUtility.IsAllAssetsCachedAndUpdated(inputSources, alreadyCached, newPrefabOutputPath)) { // not cached, create new. UnityEngine.Object prefabFile = PrefabUtility.CreateEmptyPrefab(newPrefabOutputPath); // export prefab data. PrefabUtility.ReplacePrefab(baseObject, prefabFile); // save prefab. AssetDatabase.Refresh(ImportAssetOptions.ImportRecursive); AssetDatabase.SaveAssets(); generated.Add(newPrefabOutputPath); cachedOrGenerated.Add(newPrefabOutputPath); Debug.Log(nodeName + " created new prefab: " + newPrefabOutputPath); } else { // cached. usedCache.Add(newPrefabOutputPath); cachedOrGenerated.Add(newPrefabOutputPath); Debug.Log(nodeName + " used cached prefab: " + newPrefabOutputPath); } isPrefabricateFunctionCalled = true; return(newPrefabOutputPath); }; if (!Directory.Exists(recommendedPrefabPath)) { // create recommended directory. Directory.CreateDirectory(recommendedPrefabPath); } /* * execute inheritee's input method. */ try { CreatePrefab(nodeName, nodeId, groupKey, assets, recommendedPrefabPath, Prefabricate); } catch (Exception e) { Debug.LogError(nodeName + " Error:" + e); throw new NodeException(nodeName + " Error:" + e, nodeId); } if (!isPrefabricateFunctionCalled) { Debug.LogWarning(nodeName + ": Prefabricate delegate was not called. Prefab might not be created properly."); } /* * ready assets-output-data from this node to next output. * it contains "cached" or "generated as prefab" or "else" assets. * output all assets. */ var currentAssetsInThisNode = FileUtility.FilePathsInFolder(recommendedPrefabPath); foreach (var generatedCandidateAssetPath in currentAssetsInThisNode) { /* * candidate is new, regenerated prefab. */ if (generated.Contains(generatedCandidateAssetPath)) { var newAsset = Asset.CreateNewAssetWithImportPathAndStatus( generatedCandidateAssetPath, true, false ); outputSources.Add(newAsset); continue; } /* * candidate is not new prefab. */ var cachedPrefabAsset = Asset.CreateNewAssetWithImportPathAndStatus( generatedCandidateAssetPath, false, false ); outputSources.Add(cachedPrefabAsset); } /* * add current resources to next node's resources. */ outputSources.AddRange(inputSources); outputDict[groupKey] = outputSources; } // delete unused cached prefabs. var unusedCachePaths = alreadyCached.Except(cachedOrGenerated).Where(path => !FileUtility.IsMetaFile(path)).ToList(); foreach (var unusedCachePath in unusedCachePaths) { // unbundlize unused prefabricated cached asset. var assetImporter = AssetImporter.GetAtPath(unusedCachePath); assetImporter.assetBundleName = string.Empty; FileUtility.DeleteFileThenDeleteFolderIfEmpty(unusedCachePath); } Output(nodeId, connectionIdToNextNode, outputDict, usedCache); }
public static List <string> GetCachedDataByNodeKind(AssetBundleGraphSettings.NodeKind nodeKind, string nodeId) { var platformPackageKeyCandidate = SystemDataUtility.GetCurrentPlatformKey(); switch (nodeKind) { case AssetBundleGraphSettings.NodeKind.IMPORTSETTING_GUI: { // no cache file exists for importSetting. return(new List <string>()); } case AssetBundleGraphSettings.NodeKind.MODIFIER_GUI: { // no cache file exists for modifier. return(new List <string>()); } case AssetBundleGraphSettings.NodeKind.PREFABRICATOR_SCRIPT: case AssetBundleGraphSettings.NodeKind.PREFABRICATOR_GUI: { var cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.PREFABRICATOR_CACHE_PLACE, nodeId, platformPackageKeyCandidate ); // no cache folder, no cache. if (!Directory.Exists(cachedPathBase)) { // search default platform + package cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.PREFABRICATOR_CACHE_PLACE, nodeId, SystemDataUtility.GetDefaultPlatformKey() ); if (!Directory.Exists(cachedPathBase)) { return(new List <string>()); } } return(FileUtility.FilePathsInFolder(cachedPathBase)); } case AssetBundleGraphSettings.NodeKind.BUNDLIZER_GUI: { // do nothing. break; } case AssetBundleGraphSettings.NodeKind.BUNDLEBUILDER_GUI: { var cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE, nodeId, platformPackageKeyCandidate ); // no cache folder, no cache. if (!Directory.Exists(cachedPathBase)) { // search default platform + package cachedPathBase = FileUtility.PathCombine( AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE, nodeId, SystemDataUtility.GetDefaultPlatformKey() ); if (!Directory.Exists(cachedPathBase)) { return(new List <string>()); } } return(FileUtility.FilePathsInFolder(cachedPathBase)); } default: { // nothing to do. break; } } return(new List <string>()); }
public void Run(string nodeName, string connectionIdToNextNode, string labelToNext, Dictionary <string, List <Asset> > groupedSources, List <string> alreadyCached, Action <string, string, Dictionary <string, List <Asset> >, List <string> > Output) { var recommendedBundleOutputDirSource = FileUtility.PathCombine(AssetBundleGraphSettings.BUNDLEBUILDER_CACHE_PLACE, connectionIdToNextNode); var recommendedBundleOutputDir = FileUtility.PathCombine(recommendedBundleOutputDirSource, SystemDataUtility.GetCurrentPlatformKey()); if (!Directory.Exists(recommendedBundleOutputDir)) { Directory.CreateDirectory(recommendedBundleOutputDir); } /* * merge multi group into ["0"] group. */ var intendedAssetNames = new List <string>(); foreach (var groupKey in groupedSources.Keys) { var internalAssetsOfCurrentGroup = groupedSources[groupKey]; foreach (var internalAsset in internalAssetsOfCurrentGroup) { intendedAssetNames.Add(internalAsset.fileNameAndExtension); intendedAssetNames.Add(internalAsset.fileNameAndExtension + AssetBundleGraphSettings.MANIFEST_FOOTER); } } /* * platform's bundle & manifest. * e.g. iOS & iOS.manifest. */ var currentPlatform_Package_BundleFile = SystemDataUtility.GetCurrentPlatformKey(); var currentPlatform_Package_BundleFileManifest = currentPlatform_Package_BundleFile + AssetBundleGraphSettings.MANIFEST_FOOTER; intendedAssetNames.Add(currentPlatform_Package_BundleFile); intendedAssetNames.Add(currentPlatform_Package_BundleFileManifest); /* * delete not intended assets. */ foreach (var alreadyCachedPath in alreadyCached) { var cachedFileName = Path.GetFileName(alreadyCachedPath); if (intendedAssetNames.Contains(cachedFileName)) { continue; } File.Delete(alreadyCachedPath); } var assetBundleOptions = BuildAssetBundleOptions.None; foreach (var enabled in bundleOptions) { switch (enabled) { case "Uncompressed AssetBundle": { assetBundleOptions = assetBundleOptions | BuildAssetBundleOptions.UncompressedAssetBundle; break; } case "Disable Write TypeTree": { assetBundleOptions = assetBundleOptions | BuildAssetBundleOptions.DisableWriteTypeTree; break; } case "Deterministic AssetBundle": { assetBundleOptions = assetBundleOptions | BuildAssetBundleOptions.DeterministicAssetBundle; break; } case "Force Rebuild AssetBundle": { assetBundleOptions = assetBundleOptions | BuildAssetBundleOptions.ForceRebuildAssetBundle; break; } case "Ignore TypeTree Changes": { assetBundleOptions = assetBundleOptions | BuildAssetBundleOptions.IgnoreTypeTreeChanges; break; } case "Append Hash To AssetBundle Name": { assetBundleOptions = assetBundleOptions | BuildAssetBundleOptions.AppendHashToAssetBundleName; break; } #if UNITY_5_3 case "ChunkBased Compression": { assetBundleOptions = assetBundleOptions | BuildAssetBundleOptions.ChunkBasedCompression; break; } #endif } } BuildPipeline.BuildAssetBundles(recommendedBundleOutputDir, assetBundleOptions, EditorUserBuildSettings.activeBuildTarget); /* * check assumed bundlized resources and actual generated assetbundles. * * "assuned bundlized resources info from bundlizer" are contained by "actual bundlized resources". */ var outputDict = new Dictionary <string, List <Asset> >(); var outputSources = new List <Asset>(); var newAssetPaths = new List <string>(); var generatedAssetBundlePaths = FileUtility.FilePathsInFolder(recommendedBundleOutputDir); foreach (var newAssetPath in generatedAssetBundlePaths) { newAssetPaths.Add(newAssetPath); var newAssetData = Asset.CreateAssetWithImportPath(newAssetPath); outputSources.Add(newAssetData); } // compare, erase & notice. var containedAssetBundles = new List <string>(); // collect intended output. foreach (var generatedAssetPath in newAssetPaths) { var generatedAssetName = Path.GetFileName(generatedAssetPath); // collect intended assetBundle & assetBundleManifest file. foreach (var bundledName in intendedAssetNames) { if (generatedAssetName == bundledName) { containedAssetBundles.Add(generatedAssetPath); continue; } var bundleManifestName = bundledName + AssetBundleGraphSettings.MANIFEST_FOOTER; if (generatedAssetName == bundleManifestName) { containedAssetBundles.Add(generatedAssetPath); continue; } } } var diffs = newAssetPaths.Except(containedAssetBundles); foreach (var diff in diffs) { Debug.LogWarning(nodeName + ": AssetBundle " + diff + " is not intended to build. Check if unnecessary importer or prefabricator exists in the graph."); } outputDict["0"] = outputSources; var usedCache = new List <string>(alreadyCached); Output(connectionIdToNextNode, labelToNext, outputDict, usedCache); }
public void Setup(string nodeName, string nodeId, string connectionIdToNextNode, Dictionary <string, List <Asset> > unused, List <string> alreadyCached, Action <string, string, Dictionary <string, List <Asset> >, List <string> > Output) { try { ValidateLoadPath( loadFilePath, loadFilePath, () => { //throw new NodeException(nodeName + ": Load Path is empty.", nodeId); }, () => { throw new NodeException(nodeName + ": Directory not found: " + loadFilePath, nodeId); } ); } catch (NodeException e) { AssetBundleGraphEditorWindow.AddNodeException(e); return; } // SOMEWHERE_FULLPATH/PROJECT_FOLDER/Assets/ var assetsFolderPath = Application.dataPath + AssetBundleGraphSettings.UNITY_FOLDER_SEPARATOR; var outputSource = new List <Asset>(); var targetFilePaths = FileUtility.FilePathsInFolder(loadFilePath); try { foreach (var targetFilePath in targetFilePaths) { if (targetFilePath.Contains(AssetBundleGraphSettings.ASSETBUNDLEGRAPH_PATH)) { continue; } // already contained into Assets/ folder. // imported path is Assets/SOMEWHERE_FILE_EXISTS. if (targetFilePath.StartsWith(assetsFolderPath)) { var relativePath = targetFilePath.Replace(assetsFolderPath, AssetBundleGraphSettings.ASSETS_PATH); var assetType = TypeUtility.GetTypeOfAsset(relativePath); if (assetType == typeof(object)) { continue; } outputSource.Add(Asset.CreateNewAssetFromLoader(targetFilePath, relativePath)); continue; } throw new NodeException(nodeName + ": Invalid Load Path. Path must start with Assets/", nodeId); } } catch (NodeException e) { AssetBundleGraphEditorWindow.AddNodeException(e); return; } catch (Exception e) { Debug.LogError(nodeName + " Error:" + e); } var outputDir = new Dictionary <string, List <Asset> > { { "0", outputSource } }; Output(nodeId, connectionIdToNextNode, outputDir, new List <string>()); }