private static bool findExistingPrefab(string modelPath, PrefabLabSettings settings, out string foundPrefabPath) { foundPrefabPath = null; string relativeSubdir = modelPath.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1); relativeSubdir = relativeSubdir.Remove(relativeSubdir.LastIndexOf("/") + 1); string relativeDestinationFolder = settings.DestinationFolder + "/" + relativeSubdir; string modelName = Path.GetFileNameWithoutExtension(modelPath); //find filepath DirectoryInfo di = new DirectoryInfo(Application.dataPath + "/" + relativeDestinationFolder); if (di.Exists) { foreach (FileInfo fi in di.GetFiles()) { if (Path.GetFileNameWithoutExtension(fi.Name) == modelName + settings.PrefabSuffix) { foundPrefabPath = relativeDestinationFolder + fi.Name; return(true); } } } return(false); }
public static void UpdatePrefabs(Object[] objects, PrefabLabSettings settings) { for (int i = 0; i < objects.Length; i++) { string assetPath = AssetDatabase.GetAssetPath(objects[i].GetInstanceID()); if (assetPath.IndexOf("Assets/" + settings.DestinationFolder) != -1) { if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.Prefab) { string modelPath; if (findExistingModel(assetPath, settings, out modelPath)) { UpdatePrefab("Assets/" + modelPath, settings); } } } if (assetPath.IndexOf("Assets/" + settings.SourceFolder) != -1) { if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.ModelPrefab) { UpdatePrefab(assetPath, settings); } } } }
public static Object[] GetModelsOrPrefabs(Object[] objects, PrefabLabSettings settings) { List <Object> newObjects = new List <Object>(); for (int i = 0; i < objects.Length; i++) { string assetPath = AssetDatabase.GetAssetPath(objects[i].GetInstanceID()); if (assetPath.IndexOf("Assets/" + settings.DestinationFolder) != -1) { if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.Prefab) { string modelPath; if (findExistingModel(assetPath, settings, out modelPath)) { newObjects.Add(AssetDatabase.LoadMainAssetAtPath("Assets/" + modelPath)); } } } if (assetPath.IndexOf("Assets/" + settings.SourceFolder) != -1) { if (PrefabUtility.GetPrefabType(objects[i]) == PrefabType.ModelPrefab) { string prefabPath; if (findExistingPrefab(assetPath, settings, out prefabPath)) { newObjects.Add(AssetDatabase.LoadMainAssetAtPath("Assets/" + prefabPath)); } } } } return(newObjects.Count == 0 ? null : newObjects.ToArray()); }
public override void OnInspectorGUI() { PrefabLabData PLD = target as PrefabLabData; if (PLD.Type == PrefabLabObjectType.Old) { EditorGUILayout.Space(); EditorGUILayout.HelpBox("This is an old prefab. Please update the prefab to see new features", MessageType.Info, true); } else if (PLD.Type == PrefabLabObjectType.Root) { EditorGUILayout.Space(); PLD.ImportAnimationsAutomatically = EditorGUILayout.Toggle("Import Animations", PLD.ImportAnimationsAutomatically, EditorStyles.toggle); EditorGUILayout.Space(); if (PLD.SkinnedMeshes) { EditorGUILayout.HelpBox("SkinnedMeshRenderers are not supported yet. To update a skinned mesh correctly select the skinned GameObject and follow instructions. TIP: Try to avoid adding components and GameObjects to the skinned object and it's bones.", MessageType.Warning, true); } } else if (PLD.Type == PrefabLabObjectType.SkinnedMesh) { EditorGUILayout.Space(); EditorGUILayout.HelpBox("SkinnedMeshRenderers are not supported yet. To update a skinned mesh correctly you have to delete this gameObject, and all the bones used by this component. Apply the Prefab and update the prefab", MessageType.Warning, true); } EditorGUILayout.Space(); if (GUILayout.Button("Update Prefab")) { string path = AssetDatabase.GetAssetPath(PrefabUpdater.GetInstanceIDOfSceneAndProjectObject(PLD.gameObject)); PrefabLabSettings settings = PrefabUpdater.GetPrefabLabSettings(); PrefabUpdater.UpdatePrefab(settings, path); } if (GUILayout.Button("Select Model")) { PrefabLabSettings settings = PrefabUpdater.GetPrefabLabSettings(); Object[] newSelection = PrefabUpdater.GetModelsOrPrefabs( new Object[] { AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(PrefabUpdater.GetInstanceIDOfSceneAndProjectObject(PLD.gameObject)), typeof(Object)) }, settings); if (newSelection != null) { Selection.objects = newSelection; } else { Debug.Log("There was no prefab lab object found"); } } EditorGUILayout.Space(); }
public static void UpdatePrefab(PrefabLabSettings settings, string prefabPath) { string modelPath; if (findExistingModel(prefabPath, settings, out modelPath)) { UpdatePrefab("Assets/" + modelPath, settings); } }
private static void deletePrefab(string assetPath, PrefabLabSettings settings) { string prefabPath; if (findExistingPrefab(assetPath, settings, out prefabPath)) { AssetDatabase.DeleteAsset("Assets/" + prefabPath); } }
public static PrefabLabSettings GetPrefabLabSettings() { //Read PrefabUpdater settings PrefabLabSettings settings = PrefabLabSettings.Defaults; if (File.Exists(PrefabLabSettings.Filepath)) { settings.ReadSettingsFromDisk(); } return(settings); }
public override int GetPostprocessOrder() { //Read PrefabUpdater settings PrefabLabSettings settings = PrefabLabSettings.Defaults; if (File.Exists(PrefabLabSettings.Filepath)) { settings.ReadSettingsFromDisk(); } return(settings.PostProcessOrder); }
public static void UpdatePrefab() { //Read PrefabUpdater settings PrefabLabSettings settings = PrefabLabSettings.Defaults; if (File.Exists(PrefabLabSettings.Filepath)) { settings.ReadSettingsFromDisk(); } PrefabUpdater.UpdatePrefabs(Selection.objects, settings); }
public static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { //Read PrefabUpdater settings PrefabLabSettings settings = PrefabLabSettings.Defaults; if (File.Exists(PrefabLabSettings.Filepath)) { settings.ReadSettingsFromDisk(); } //Move assets List <string> filteredMovedFromAssets; List <string> filteredMoveAssets = filterAssets(movedAssets, settings.SourceFolder, PrefabType.ModelPrefab, movedFromAssetPaths, out filteredMovedFromAssets); for (int i = 0; i < filteredMoveAssets.Count; i++) { moveAndRenameAsset(filteredMoveAssets[i], filteredMovedFromAssets[i], settings); } //Delete assets List <string> filteredDeletedAssets = filterAssets(deletedAssets, settings.SourceFolder); foreach (string asset in filteredDeletedAssets) { deletePrefab(asset, settings); } //Import assets List <string> filteredImportAssets = filterAssets(importedAssets, settings.SourceFolder, PrefabType.ModelPrefab); foreach (string asset in filteredImportAssets) { UpdatePrefab(asset, settings); } //Debug /*foreach (string str in importedAssets) * Debug.Log("Reimported Asset: " + str); * * foreach (string str in deletedAssets) * Debug.Log("Deleted Asset: " + str); * * for (int i = 0; i < movedAssets.Length; i++) * Debug.Log("Moved Asset: " + movedAssets[i] + " from: " + movedFromAssetPaths[i]);*/ }
//Rename MetaData.Data from NewModelNameSuffix to CurrentModelNameSuffix //(New and Current exist so we can detect whether an gameobject has just been imported or its an older part of the prefab) private static void RenameNewToCurrent(GameObject root, PrefabLabSettings settings) { PrefabLabData metadata = root.GetComponent <PrefabLabData>(); if (metadata != null) { if (metadata.Data == NewModelNameSuffix) { metadata.Data = settings.ModelMetadata; } } for (int i = 0; i < root.transform.childCount; i++) { RenameNewToCurrent(root.transform.GetChild(i).gameObject, settings); } }
public static void ShowWindow() { if (File.Exists(PrefabLabSettings.Filepath)) { settings.ReadSettingsFromDisk(); } else { settings = PrefabLabSettings.Defaults; } EditorWindow window = EditorWindow.GetWindow(typeof(PrefabLabWindow), true); Rect windowRect = new Rect(200, 300, 320, 460); window.position = windowRect; window.title = "Merlin's Prefab Lab"; }
public static void SelectPrefabOrModel() { //Read PrefabUpdater settings PrefabLabSettings settings = PrefabLabSettings.Defaults; if (File.Exists(PrefabLabSettings.Filepath)) { settings.ReadSettingsFromDisk(); } Object[] newSelection = PrefabUpdater.GetModelsOrPrefabs(Selection.objects, settings); if (newSelection != null) { Selection.objects = newSelection; } else { Debug.Log("There was no prefab lab object found"); } }
private static void moveAndRenameAsset(string movedAsset, string movedFromAssetPath, PrefabLabSettings settings) { //Substract subdirs from imported asset string oldRelativeSubdir = movedFromAssetPath.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1); oldRelativeSubdir = oldRelativeSubdir.Remove(oldRelativeSubdir.LastIndexOf("/") + 1); string oldRelativeDestinationFolder = settings.DestinationFolder + "/" + oldRelativeSubdir; string oldAssetName = Path.GetFileNameWithoutExtension(movedFromAssetPath); string oldAssetPath; if (findExistingPrefab(oldAssetName, oldRelativeDestinationFolder, settings.PrefabSuffix, out oldAssetPath)) { string relativeSubdir = movedAsset.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1); relativeSubdir = relativeSubdir.Remove(relativeSubdir.LastIndexOf("/") + 1); string relativeDestinationFolder = settings.DestinationFolder + "/" + relativeSubdir; string absoluteSubdir = Application.dataPath + "/" + relativeDestinationFolder; string newAssetName = Path.GetFileNameWithoutExtension(movedAsset); string newAssetPath = "Assets/" + relativeDestinationFolder + newAssetName + settings.PrefabSuffix + ".prefab"; oldAssetPath = "Assets/" + oldAssetPath; Directory.CreateDirectory(absoluteSubdir); AssetDatabase.MoveAsset(oldAssetPath, newAssetPath); Debug.Log("From: " + oldAssetPath + " To: " + newAssetPath + " absoluteSubdir: " + absoluteSubdir); if (oldAssetName != newAssetName) { GameObject GO = (GameObject)AssetDatabase.LoadAssetAtPath(newAssetPath, typeof(GameObject)); GetChildByName(oldAssetName, GO).name = newAssetName; } } }
public static void UpdatePrefab(string modelPath, PrefabLabSettings settings) { //Substract subdirs from imported asset string relativeSubdir = modelPath.Remove(0, ("Assets/" + settings.SourceFolder).Length + 1); relativeSubdir = relativeSubdir.Remove(relativeSubdir.LastIndexOf("/") + 1); string relativeSourceFolder = settings.DestinationFolder + "/" + relativeSubdir; string absoluteSubdir = Application.dataPath + "/" + relativeSourceFolder; //Prepare the imported model for modification GameObject importedModel = (GameObject)PrefabUtility.InstantiatePrefab(AssetDatabase.LoadAssetAtPath(modelPath, typeof(GameObject))); AddMetaData(importedModel); GameObject lostObjects = null; Object originalPrefab; if (!FindExistingPrefab(importedModel.name, relativeSourceFolder, settings.PrefabSuffix, out originalPrefab)) { //Create subdirs Directory.CreateDirectory(absoluteSubdir); AssetDatabase.Refresh(); //Prefab not found, create one for me please! string prefabFilepath = "Assets/" + relativeSourceFolder + importedModel.name + settings.PrefabSuffix + ".prefab"; Object emptyPrefab = PrefabUtility.CreateEmptyPrefab(prefabFilepath); AssetDatabase.ImportAsset(prefabFilepath); //Creating an empty prefab is really empty so we need a gameobject to start with, called parent GameObject parent = new GameObject(importedModel.name + settings.PrefabSuffix); PrefabLabData PLD = parent.AddComponent <PrefabLabData>(); PLD.Type = PrefabLabObjectType.Root; //Mark as max model UpdateMetaDataRecursively(importedModel, settings.ModelMetadata, PLD); //Copy newModel to prefab importedModel.transform.parent = parent.transform; originalPrefab = PrefabUtility.ReplacePrefab(parent, emptyPrefab, ReplacePrefabOptions.ReplaceNameBased); //Clean up GameObject.DestroyImmediate(parent); } else { GameObject prefab = (GameObject)GameObject.Instantiate(originalPrefab); prefab.name = originalPrefab.name; PrefabLabData PLD = prefab.GetComponent <PrefabLabData>(); if (PLD == null) { PLD = prefab.AddComponent <PrefabLabData>(); PLD.Type = PrefabLabObjectType.Root; } //Find LostObjects root or create it lostObjects = GetChildByName(lostObjectsName, prefab); if (lostObjects == null) { lostObjects = new GameObject(lostObjectsName); lostObjects.transform.parent = prefab.transform; } //Find newModel root in merlin's prefab and do magic GameObject prefabModelRoot = GetChildByName(importedModel.name, prefab); if (prefabModelRoot != null) { //Check if object changed from one object to multiple if ((prefabModelRoot.transform.GetChildCount() == 0 && importedModel.transform.GetChildCount() != 0) || (prefabModelRoot.transform.GetChildCount() != 0 && importedModel.transform.GetChildCount() == 0)) { prefabModelRoot.transform.parent = lostObjects.transform; #if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_3_6 prefabModelRoot.SetActiveRecursively(false); #else prefabModelRoot.SetActive(false); #endif prefabModelRoot = null; Debug.LogWarning("Unity treats model files with one object differently than files with multiple objects. You changed in the number of objects in " + importedModel.name + ". We recovered the old gameobjects in LostObjects."); } } if (prefabModelRoot == null) { UpdateMetaDataRecursively(importedModel, settings.ModelMetadata, PLD); importedModel.transform.parent = prefab.transform; importedModel.transform.localPosition = Vector3.zero; } else { //Mark the newly imported as new to know later on if a modelpart has just been imported or its an old prefabpart UpdateMetaDataRecursively(importedModel, NewModelNameSuffix, PLD); //Does all the magic to childs RebuildPrefab(importedModel, prefabModelRoot, modelPath, PLD); RescueAndRemove(importedModel, prefabModelRoot, lostObjects); RenameNewToCurrent(prefabModelRoot.gameObject, settings); //Don't forget the parent CopyComponents(importedModel, prefabModelRoot, modelPath, PLD); } //Clean up if no lostobjects have been found if (lostObjects.transform.childCount > 0) { #if UNITY_3_0 || UNITY_3_1 || UNITY_3_2 || UNITY_3_3 || UNITY_3_4 || UNITY_3_5 || UNITY_3_6 lostObjects.SetActiveRecursively(false); #else lostObjects.SetActive(false); #endif Debug.Log("Prefab Lab Warning: There are " + lostObjects.transform.childCount + " objects found which don't have a parent anymore because it has been deleted in the model." + System.Environment.NewLine + "To recover these objects, browse to the gameobject \"" + lostObjectsName + "\" in the prefab " + prefab.name + ".", originalPrefab); } else { GameObject.DestroyImmediate(lostObjects); } //Save created or modified prefab PrefabUtility.ReplacePrefab(prefab, originalPrefab, ReplacePrefabOptions.ReplaceNameBased); //Clean up GameObject.DestroyImmediate(importedModel); GameObject.DestroyImmediate(prefab); } }