// Load button action private void LoadButtonAction() { string oChosenPath = EditorUtility.OpenFilePanel( "Load a prefab to replace the selected object", GetLastFilePath(), "prefab"); if (oChosenPath.Length != 0) { // Check if the path is in the asset folder if (oChosenPath.Contains(Application.dataPath)) { string oAssetPath = Application.dataPath; oAssetPath = oAssetPath.Replace("Assets", ""); string oLocalChosenPath = oChosenPath; oLocalChosenPath = oLocalChosenPath.Replace(oAssetPath, ""); // Load NestedPrefabEditorUtility.LoadPrefab(ref m_rSelectedGameObject, oLocalChosenPath); Selection.activeGameObject = m_rSelectedGameObject; // Remember the chosen path relative to asset path SetLastFilePath(oChosenPath); } else { Debug.LogError("Please choose an emplacement included in the Asset folder."); } } }
// Save as hierarchical prefab public static bool SaveAsHierarchicalPrefab(GameObject a_rGameObjectToSave, string a_rSavePath) { // Convert to hierarchical prefab HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = NestedPrefabEditorUtility.ConvertIntoHierarchicalPrefab(a_rGameObjectToSave); // The prefab to save into Object rPrefabObjectToSaveInto = AssetDatabase.LoadAssetAtPath(a_rSavePath, typeof(Object)); // Check if the hierarchical prefab is cyclic if (IsHierarchicalPrefabInstanceCyclic(rHierarchicalPrefabInstanceModel, rPrefabObjectToSaveInto)) { Debug.LogError("You can't create cyclic hierarchy!"); rHierarchicalPrefabInstanceModel.RevertToHierarchicalPrefab(); return(false); } // Save into a prefab at save path if (rPrefabObjectToSaveInto == null) { rPrefabObjectToSaveInto = PrefabUtility.CreateEmptyPrefab(a_rSavePath); } else { // If an object replace a prefab copy the replaced prefab version number // To the one replacing if (rPrefabObjectToSaveInto != rHierarchicalPrefabInstanceModel.HierarchicalPrefab) { // Try to get the hierarchical prefab instance model of the soon to de replaced prefab GameObject rPrefabToBeReplacedGameObject = NestedPrefabEditorUtility.GetPrefabGameObject(rPrefabObjectToSaveInto); if (rPrefabToBeReplacedGameObject != null) { HierarchicalPrefabInstance rHierarchicalPrefabInstanceModelToBeReplaced = rPrefabToBeReplacedGameObject.GetComponent <HierarchicalPrefabInstance>(); if (rHierarchicalPrefabInstanceModelToBeReplaced != null) { // Copy the version number of the instance to be replaced rHierarchicalPrefabInstanceModel.CopyVersionNumber(rHierarchicalPrefabInstanceModelToBeReplaced); } } } } // Notify model instance of it's saving rHierarchicalPrefabInstanceModel.OnSaveModelInstanceBeforePrefabReplacement(PrefabUtility.GetPrefabObject(rPrefabObjectToSaveInto)); #if BEFORE_UNITY_4_3 EditorUtility.ReplacePrefab(a_rGameObjectToSave, rPrefabObjectToSaveInto, ReplacePrefabOptions.ConnectToPrefab); #else PrefabUtility.ReplacePrefab(a_rGameObjectToSave, rPrefabObjectToSaveInto, ReplacePrefabOptions.ConnectToPrefab); #endif // Compilation is not up to date NestedPrefabEditorSettings.MustCompile = true; return(true); }
// Ensure the prefab validity : // Either a functionning hierarchical prefab or a clean classic prefab. public static void EnsurePrefabValidity(GameObject a_rPrefabGameObjectToCheck) { // If the prefab is still valid don't bother updating it HierarchicalPrefabInstance rHierarchicalPrefabInstanceModel = a_rPrefabGameObjectToCheck.GetComponent <HierarchicalPrefabInstance>(); if (rHierarchicalPrefabInstanceModel == null || rHierarchicalPrefabInstanceModel.IsValid() == false) { // If it's not a hierarchical prefab, ensure that the prefab is clean NestedPrefabEditorUtility.DisconnectResourceFromHierarchicalPrefab(a_rPrefabGameObjectToCheck); } }
// Disconnect button action private void DisconnectButtonAction() { if (EditorUtility.IsPersistent(m_rSelectedGameObject)) { NestedPrefabEditorUtility.DisconnectResourceFromHierarchicalPrefab(m_rSelectedGameObject); } else { NestedPrefabEditorUtility.DisconnectFromHierarchicalPrefabAndFromClassicPrefab(ref m_rSelectedGameObject); Selection.activeGameObject = m_rSelectedGameObject; } }
// On Hierarchical prefab update public void OnHierarchicalPrefabUpdate(HierarchicalPrefabInstance a_rHierarchicalInstanceCaller) { if (this != null) { // if the connection with the hierarchical prefab is broken if (HierarchicalPrefab == null) { // If the prefab is still there and has just been replaced if (m_rPrefabObject != null) { // Try to grab the nested prefab data from the potential instantiator NestedPrefabData rNestedPrefabData = TryGrabNestedPrefabData(); // Replace the current object by an instance of the new prefab GameObject rNewInstance = PrefabUtility.InstantiatePrefab(NestedPrefabEditorUtility.GetPrefabGameObject(m_rPrefabObject)) as GameObject; HierarchicalPrefabInstance rNewHierarchicalPrefabInstance = rNewInstance.GetComponent <HierarchicalPrefabInstance>(); // If nested if (rNestedPrefabData != null && rNewHierarchicalPrefabInstance != null && transform.parent != null) { rNewHierarchicalPrefabInstance.ReloadNestedPrefabData(rNestedPrefabData); // Change the parent without changing the local transform information NestedPrefabUtility.ChangeParentAndKeepSameLocalTransform(rNewHierarchicalPrefabInstance.transform, transform.parent); } else { Vector3 f3LocalScaleSave = rNewInstance.transform.localScale; rNewInstance.transform.parent = transform.parent; rNewInstance.transform.localPosition = transform.localPosition; rNewInstance.transform.localRotation = transform.localRotation; rNewInstance.transform.localScale = f3LocalScaleSave; } // Auto destruction Editor.DestroyImmediate(gameObject); } } else { // Revert to hierarchical prefab //RevertToHierarchicalPrefab(); if (this == a_rHierarchicalInstanceCaller) { // if it's the updated instance we just redeploy the hierarchy DeployHierarchy(); } else { // Revert to hierarchical prefab RevertToHierarchicalPrefab(); } } } }
// Revert to the hierarchical prefab public void ApplyChangesToHierarchicalPrefab() { // Try to get the prefab parent GameObject rHierarchicalPrefab = HierarchicalPrefab; if(rHierarchicalPrefab != null) { // Get the prefab path string oPrefabPath = AssetDatabase.GetAssetPath(rHierarchicalPrefab); // Save the prefab at this path if(NestedPrefabEditorUtility.SaveAsHierarchicalPrefab(gameObject, oPrefabPath)) { // Ensure the disconnection PrefabUtility.DisconnectPrefabInstance(gameObject); // Notify the other instances NestedPrefabEditorUtility.NotifyInstancesOfHierarchicalPrefabUpdate(m_rPrefabObject, this); } } }
// Disconnect button action public static void DisconnectFromHierarchicalPrefabAndFromClassicPrefab(ref GameObject a_rGameObjectToDisconnect) { // Erase all nested prefabs specific components NestedPrefabEditorUtility.DestroyComponentsInChildren <HierarchicalPrefabInstance>(a_rGameObjectToDisconnect); NestedPrefabEditorUtility.DestroyComponentsInChildren <NestedPrefabsInstantiator>(a_rGameObjectToDisconnect); // Duplicate GameObject rGameObjectDisconnectedClone = Editor.Instantiate(a_rGameObjectToDisconnect) as GameObject; rGameObjectDisconnectedClone.name = a_rGameObjectToDisconnect.name; rGameObjectDisconnectedClone.transform.parent = a_rGameObjectToDisconnect.transform.parent; rGameObjectDisconnectedClone.transform.localPosition = a_rGameObjectToDisconnect.transform.localPosition; rGameObjectDisconnectedClone.transform.localRotation = a_rGameObjectToDisconnect.transform.localRotation; rGameObjectDisconnectedClone.transform.localScale = a_rGameObjectToDisconnect.transform.localScale; // Destroy the game object to disconnect Editor.DestroyImmediate(a_rGameObjectToDisconnect); // Change the ref to the cloned object a_rGameObjectToDisconnect = rGameObjectDisconnectedClone; }
// Save as button action private void SaveAsButtonAction() { // Chose path string oChosenPath = EditorUtility.SaveFilePanel( "Save as ...", GetLastFilePath(), m_rSelectedGameObject.name + ".prefab", "prefab"); // If a path has been selected if (oChosenPath.Length != 0) { // Check if the path is in the asset folder if (oChosenPath.Contains(Application.dataPath)) { string oAssetPath = Application.dataPath; oAssetPath = oAssetPath.Replace("Assets", ""); string oLocalChosenPath = oChosenPath; oLocalChosenPath = oLocalChosenPath.Replace(oAssetPath, ""); // Save if (NestedPrefabEditorUtility.SaveAsHierarchicalPrefab(m_rSelectedGameObject, oLocalChosenPath)) { // Ensure the disconnection PrefabUtility.DisconnectPrefabInstance(m_rSelectedGameObject); // Notify the other instances NestedPrefabEditorUtility.NotifyInstancesOfHierarchicalPrefabUpdate(m_rSelectedGameObject.GetComponent <HierarchicalPrefabInstance>().PrefabObject); } // Remember the chosen path SetLastFilePath(oChosenPath); } else { Debug.LogError("Please choose an emplacement included in the Asset folder."); } } }
// Compile the hierarchical prefab public void Compile() { // Instantiate a copy of us GameObject rHierarchicalPrefabToBeCompiledGameObject = PrefabUtility.InstantiatePrefab(gameObject) as GameObject; // Force the hierarchy to deploy HierarchicalPrefabInstance rHierarchicalPrefabToBeCompiled = rHierarchicalPrefabToBeCompiledGameObject.GetComponent <HierarchicalPrefabInstance>(); rHierarchicalPrefabToBeCompiled.DeployHierarchy(); // Disconnect from the hierarchical prefab world NestedPrefabEditorUtility.DisconnectFromHierarchicalPrefab(rHierarchicalPrefabToBeCompiledGameObject); // Ensure the compilation directory exist Directory.CreateDirectory(Application.dataPath.Replace("Assets", "") + mc_oCompiledHierarchicalPrefabFolderPath); // Prefab object into which to save Object rPrefabObject; if (m_rCompiledHierarchicalPrefab == null) { // Ensure we have a unique save path string oSavingPath = mc_oCompiledHierarchicalPrefabFolderPath + "/" + rHierarchicalPrefabToBeCompiledGameObject.name + ".prefab"; oSavingPath = AssetDatabase.GenerateUniqueAssetPath(oSavingPath); // Save it into a prefab rPrefabObject = PrefabUtility.CreateEmptyPrefab(oSavingPath); } else { rPrefabObject = PrefabUtility.GetPrefabObject(m_rCompiledHierarchicalPrefab); } GameObject rPrefabGameObject = PrefabUtility.ReplacePrefab(rHierarchicalPrefabToBeCompiledGameObject, rPrefabObject); // Link the instance model to the prefab m_rCompiledHierarchicalPrefab = rPrefabGameObject; // Destroy the instance Editor.DestroyImmediate(rHierarchicalPrefabToBeCompiledGameObject); }
// Disconnect button action public static void DisconnectResourceFromHierarchicalPrefab(GameObject a_rGameObjectToDisconnect) { // Erase all nested prefabs specific components NestedPrefabEditorUtility.DestroyComponentsInChildrenOnResource <HierarchicalPrefabInstance>(a_rGameObjectToDisconnect); NestedPrefabEditorUtility.DestroyComponentsInChildrenOnResource <NestedPrefabsInstantiator>(a_rGameObjectToDisconnect); }
// Destroy the nested prefabs private void DestroyNestedPrefabs() { NestedPrefabEditorUtility.ClearHierarchicalPrefab(gameObject); }