// Revert to the hierarchical prefab public void RevertToHierarchicalPrefab() { // If it is nested in an instance of same prefab take some care Transform rSamePrefabParent; Vector3 f3LocalPositionSave; Quaternion oLocalRotationSave; SaveNestedPlaceIfCyclic(out rSamePrefabParent, out f3LocalPositionSave, out oLocalRotationSave); // Remove nested hierarchical instance of same prefab RemoveNestedHierarchicalInstanceOfSamePrefab(); // Try to grab the nested prefab data from the potential instantiator NestedPrefabData rNestedPrefabData = TryGrabNestedPrefabData(); PrefabUtility.ReconnectToLastPrefab(gameObject); if (this != null) { ReloadNestedPrefabData(rNestedPrefabData); PrefabUtility.DisconnectPrefabInstance(gameObject); ForcePrefabInformationUpdate(); TriggerAllInstantiators(); // If we were working on a hierarchical instance nested in a instance of same prefab RestoreNestedPlaceIfCyclic(rSamePrefabParent, f3LocalPositionSave, oLocalRotationSave); } }
void GeneratePrefab(NestedPrefabData prefabData) { // Debug.Log("NestedPrefab::GeneratePrefab - prefabData " + prefabData.prefabPath + " "); Transform parent = GetHierarchyTransform(prefabData.hierarchyPathId); GameObject clone = prefabGenerator.GenerateFrom(prefabData.prefabPath); if (clone == null) { Debug.LogError("Error when trying to generate prefab " + prefabData.prefabPath + " !", this); } clone.transform.parent = parent; prefabData.CopyDataTo(clone.transform); // Recursive generation NestedPrefab nestedPrefab = clone.GetComponent <NestedPrefab>(); if (nestedPrefab != null) { nestedPrefab.prefabGenerator = prefabGenerator; nestedPrefab.GeneratePrefabs(false); // Avoid to ask permission twice } }
// Get the nested prefab data public static NestedPrefabData GetNestedPrefabData(GameObject a_rNestedPrefabGameObject) { NestedPrefabData rNestedPrefabData = new NestedPrefabData(); rNestedPrefabData.SaveModifications(a_rNestedPrefabGameObject); return(rNestedPrefabData); }
void GeneratePrefab(NestedPrefabData prefabData) { Transform parent = GetHierarchyTransform(prefabData.hierarchyPathId); GameObject clone = prefabGenerator.GenerateFrom(prefabData.prefabPath); clone.transform.parent = parent; prefabData.CopyDataTo(clone.transform); }
// 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(); } } } }
// Instantiate a nested prefab private void InstantiateNestedPrefab(NestedPrefabData a_rNestedPrefabData) { // Instantiate the prefab GameObject rNestedPrefabInstantiated = PrefabUtility.InstantiatePrefab(a_rNestedPrefabData.Prefab) as GameObject; if (rNestedPrefabInstantiated != null) { // Load its property modifications a_rNestedPrefabData.LoadModifications(rNestedPrefabInstantiated); // Change the parent without changing the local transform information NestedPrefabUtility.ChangeParentAndKeepSameLocalTransform(rNestedPrefabInstantiated.transform, gameObject.transform); } }
// Reload the nested prefab data (either by its reloading instantiator prefab data or revert to prefab resource) private void ReloadNestedPrefabData(NestedPrefabData a_rNestedPrefabData) { // If there is a nested prefab data if (a_rNestedPrefabData != null) { // Reload property modification a_rNestedPrefabData.LoadModifications(gameObject); return; } // If it doesn't has a instantiator revert to resource PrefabUtility.RevertPrefabInstance(gameObject); }
// Try to reinstantiate a hierarchical prefab public bool TryToReloadData(HierarchicalPrefabInstance a_rHierarchicalPrefabInstance) { // Try to find a prefab data corresponding to the hierarchical prefab NestedPrefabData rNestedPrefabData = TryGrabNestedPrefabData(a_rHierarchicalPrefabInstance.gameObject); if (rNestedPrefabData != null) { // Load its property modifications rNestedPrefabData.LoadModifications(a_rHierarchicalPrefabInstance.gameObject); return(true); } return(false); }
private static int currentId = 0; // Id 0 corresponds to Prefab Root public void SavePrefabData(Transform trans, string relativePath, int pathId) { Transform child; GameObject prefabParent; #if UNITY_EDITOR for (int i = 0; i < trans.childCount; i++) { child = trans.GetChild(i); prefabParent = PrefabUtility.GetPrefabParent(child.gameObject) as GameObject; if (prefabParent == null) { GameObjectData goData = new GameObjectData(); currentId++; goData.id = currentId; goData.name = child.name; goData.hierarchyPath = relativePath; goData.hierarchyPathId = pathId; goData.CopyFrom(child); emptyObjectsData.Add(goData); SavePrefabData(child, relativePath + pathSeparator + child.name, goData.id); } else { NestedPrefabData data = new NestedPrefabData(); data.prefabPath = AssetDatabase.GetAssetPath(prefabParent); Debug.Log("Prefab path = " + data.prefabPath); data.hierarchyPath = relativePath; Debug.Log("prefabHierarchyPath " + data.hierarchyPath); data.hierarchyPathId = pathId; data.CopyFrom(child); nestedPrefabsData.Add(data); } } #endif }
public override void OnInspectorGUI() { base.OnInspectorGUI(); NestedPrefab nestedPrefab = target as NestedPrefab; if (nestedPrefab == null) { return; } nestedPrefab.prefabGenerator = new DefaultPrefabGeneration(); if (GUILayout.Button("Save Nested Prefabs")) { nestedPrefab.SavePrefabData(); } if (GUILayout.Button("Revert Prefabs")) { nestedPrefab.GeneratePrefabs(); } if (nestedPrefab.prefabDetailsVisibility) { EditorGUILayout.Space(); EditorGUILayout.LabelField("List of Nested Prefabs:", EditorStyles.boldLabel); EditorGUILayout.Space(); for (int i = 0; i < nestedPrefab.nestedPrefabsData.Count; i++) { NestedPrefabData prefabData = nestedPrefab.nestedPrefabsData[i]; // GameObject prefabParent = PrefabUtility.GetPrefabParent(prefabData.prefabObject) as GameObject; // string prefabPath = AssetDatabase.GetAssetPath(prefabParent); EditorGUILayout.LabelField("" + i + ". " + prefabData.hierarchyPath + " from " + prefabData.prefabPath); // PrefabUtility.GetPropertyModifications } } }