// Convert into hierarchical prefab public static void ReplacePrefabInHierarchyByInstantiator(GameObject a_rGameObjectToConvert) { // Loop through the child transforms // and search the nested prefab Transform a_rGameObjectToConvertTransform = a_rGameObjectToConvert.transform;; // If there already is a instantiator remove it NestedPrefabsInstantiator rNestedPrefabsInstantiator = a_rGameObjectToConvert.GetComponent <NestedPrefabsInstantiator>(); if (rNestedPrefabsInstantiator != null) { rNestedPrefabsInstantiator.Clear(); } // Loop in reverse to allow direct child destruction for (int i = a_rGameObjectToConvertTransform.GetChildCount() - 1; i >= 0; i--) { // Check if Prefab replacement hasn't destroy the parent if (a_rGameObjectToConvertTransform != null) { Transform rChildTransform = a_rGameObjectToConvertTransform.GetChild(i); GameObject rChildGameObject = rChildTransform.gameObject; // If we encounter a nested prefab if (IsNestedPrefab(rChildGameObject, a_rGameObjectToConvert)) { // Removing the child from the scene graph in order to avoid // unwanted prefab reconnection propagation // (A prefab instance nested into an other instance of the same prefab will // reconnect the the top most instance thus destroying the nested prefab too soon (i.e. destroying the current child) // Keep the local Transform in order to keep the override properties NestedPrefabUtility.ChangeParentAndKeepSameLocalTransform(rChildTransform, null); // Force the prefab reconnection to have an up to date property modifications PrefabUtility.ReconnectToLastPrefab(rChildGameObject); // Reconnect to the scene graph NestedPrefabUtility.ChangeParentAndKeepSameLocalTransform(rChildTransform, a_rGameObjectToConvertTransform); // Create the nested prefab instantiator on his parent NestedPrefabsInstantiator rNestedPrefabInstantiator = NestedPrefabComponentUtility.GetOrCreate <NestedPrefabsInstantiator>(a_rGameObjectToConvert); // Add the current nested prefab game object rNestedPrefabInstantiator.Add(rChildGameObject); // Destroy the nested prefab game object Editor.DestroyImmediate(rChildGameObject); } else // If not a prefab go deeper { ReplacePrefabInHierarchyByInstantiator(rChildGameObject); } } } }
// 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); } }
// Add a nested prefab to spawn public void Add(GameObject a_rNestedPrefabGameObject) { m_rNestedPrefabDatas.Add(NestedPrefabUtility.GetNestedPrefabData(a_rNestedPrefabGameObject)); }