internal static GameObject FindSelectionBase(GameObject go) { if (go == null) { return(null); } // Find prefab based base Transform prefabBase = null; if (PrefabUtility.IsPartOfNonAssetPrefabInstance(go)) { prefabBase = PrefabUtility.GetOutermostPrefabInstanceRoot(go).transform; } // Find attribute based base Transform tr = go.transform; while (tr != null) { // If we come across the prefab base, no need to search further down. if (tr == prefabBase) { return(tr.gameObject); } // If this one has the attribute, return this one. if (AttributeHelper.GameObjectContainsAttribute <SelectionBaseAttribute>(tr.gameObject)) { return(tr.gameObject); } tr = tr.parent; } // There is neither a prefab or attribute based selection root, so return null return(null); }
bool ApplyAll() { // Collect Prefab Asset paths and also check if there's more than one of the same. HashSet <string> prefabAssetPaths = new HashSet <string>(); bool multipleOfSame = false; for (int i = 0; i < m_SelectedGameObjects.Length; i++) { string prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(m_SelectedGameObjects[i]); if (prefabAssetPaths.Contains(prefabAssetPath)) { multipleOfSame = true; } else { prefabAssetPaths.Add(prefabAssetPath); } } // If more than one instance of the same Prefab Asset, show dialog to user. if (multipleOfSame && !EditorUtility.DisplayDialog( L10n.Tr("Multiple instances of same Prefab Asset"), L10n.Tr("Multiple instances of the same Prefab Asset were detected. Potentially conflicting overrides will be applied sequentially and will overwrite each other."), L10n.Tr("OK"), L10n.Tr("Cancel"))) { return(false); } // Make sure assets are checked out in version control. if (!PrefabUtility.PromptAndCheckoutPrefabIfNeeded(prefabAssetPaths.ToArray(), PrefabUtility.SaveVerb.Apply)) { return(false); } var undoStructs = new List <ApplyAllUndo>(); var actionName = "ApplyAll"; for (var i = 0; i < m_SelectedGameObjects.Length; i++) { var us = new ApplyAllUndo(); us.correspondingSourceObject = (GameObject)PrefabUtility.GetCorrespondingObjectFromSource(m_SelectedGameObjects[i]); Undo.RegisterFullObjectHierarchyUndo(us.correspondingSourceObject, actionName); // handles changes to existing objects and object what will be deleted but not objects that are created GameObject prefabInstanceRoot = PrefabUtility.GetOutermostPrefabInstanceRoot(m_SelectedGameObjects[i]); Undo.RegisterFullObjectHierarchyUndo(prefabInstanceRoot, actionName); us.prefabHierarchy = new HashSet <int>(); PrefabUtility.GetObjectListFromHierarchy(us.prefabHierarchy, us.correspondingSourceObject); undoStructs.Add(us); } // Apply sequentially. AssetDatabase.StartAssetEditing(); try { foreach (var t in m_SelectedGameObjects) { PrefabUtility.ApplyPrefabInstance(t, InteractionMode.UserAction); } } finally { AssetDatabase.StopAssetEditing(); } foreach (var t in undoStructs) { PrefabUtility.RegisterNewObjects(t.correspondingSourceObject, t.prefabHierarchy, actionName); } EditorUtility.ForceRebuildInspectors(); return(true); }
internal static void CreateEmptyParent() { Transform[] selected = Selection.transforms; GameObject defaultParentObject = SceneView.GetDefaultParentObjectIfSet()?.gameObject; string defaultParentObjectSceneGUID = defaultParentObject?.scene.guid; // Clear default parent object so we could always reparent and move the new parent to the scene we need if (defaultParentObject != null) { SceneHierarchy.ClearDefaultParentObject(defaultParentObjectSceneGUID); } // If selected object is a prefab, get the its root object if (selected.Length > 0) { for (int i = 0; i < selected.Length; i++) { if (PrefabUtility.GetPrefabAssetType(selected[i].gameObject) != PrefabAssetType.NotAPrefab) { selected[i] = PrefabUtility.GetOutermostPrefabInstanceRoot(selected[i].gameObject).transform; } } } // Selection.transform does not provide correct list order, so we have to do it manually selected = selected.ToList().OrderBy(g => g.GetSiblingIndex()).ToArray(); GameObject go = ObjectFactory.CreateGameObject("GameObject"); if (Selection.activeGameObject == null && Selection.gameObjects != null) { Selection.activeGameObject = Selection.gameObjects[0]; } if (Selection.activeGameObject != null) { go.transform.position = Selection.activeGameObject.transform.position; } GameObject parent = Selection.activeTransform != null ? Selection.activeTransform.gameObject : null; Transform sibling = null; if (parent != null) { sibling = parent.transform; parent = parent.transform.parent != null ? parent.transform.parent.gameObject : null; } Place(go, parent, false); var rectTransform = go.GetComponent <RectTransform>(); // If new parent is RectTransform, make sure its position and size matches child rect transforms if (rectTransform != null && selected != null && selected.Length > 0) { CenterRectTransform(selected, rectTransform); } if (parent == null && sibling != null) { Undo.MoveGameObjectToScene(go, sibling.gameObject.scene, "Move To Scene"); } if (parent == null && sibling == null) { go.transform.SetAsLastSibling(); } else { go.transform.MoveAfterSibling(sibling, true); } // At this point, RecordStructureChange is already ongoing (from the CreateGameObject call). // We need to flush the stack to finalise the RecordStructureChange before any of following SetTransformParent calls takes place. Undo.FlushTrackedObjects(); // Put gameObjects under a created parent if (selected.Length > 0) { foreach (var gameObject in selected) { if (gameObject != null) { Undo.SetTransformParent(gameObject.transform, go.transform, "Reparenting"); gameObject.transform.SetAsLastSibling(); } } SceneHierarchyWindow.lastInteractedHierarchyWindow.SetExpanded(go.GetInstanceID(), true); } // Set back default parent object if we have one if (defaultParentObject != null) { SceneHierarchy.UpdateSessionStateInfoAndActiveParentObjectValuesForScene(defaultParentObjectSceneGUID, defaultParentObject.GetInstanceID()); } }
internal static void CreateEmptyParent() { Transform[] selected = Selection.transforms; // If selected object is a prefab, get the its root object if (selected.Length > 0) { for (int i = 0; i < selected.Length; i++) { if (PrefabUtility.GetPrefabAssetType(selected[i].gameObject) != PrefabAssetType.NotAPrefab) { selected[i] = PrefabUtility.GetOutermostPrefabInstanceRoot(selected[i].gameObject).transform; } } } // Selection.transform does not provide correct list order, so we have to do it manually selected = selected.ToList().OrderBy(g => g.GetSiblingIndex()).ToArray(); GameObject parent = Selection.activeTransform != null ? Selection.activeTransform.gameObject : null; Transform sibling = null; if (parent != null) { sibling = parent.transform; parent = parent.transform.parent != null ? parent.transform.parent.gameObject : null; } GameObject go = ObjectFactory.CreateGameObject("GameObject"); Place(go, parent); if (parent == null && sibling != null) { Undo.MoveGameObjectToScene(go, sibling.gameObject.scene, "Move To Scene"); } if (parent == null && sibling == null) { go.transform.SetAsLastSibling(); } else { go.transform.MoveAfterSibling(sibling, true); } // Put gameObjects under a created parent if (selected.Length > 0) { foreach (var gameObject in selected) { if (gameObject != null) { Undo.SetTransformParent(gameObject.transform, go.transform, "Reparenting"); gameObject.transform.SetAsLastSibling(); } } SceneHierarchyWindow.lastInteractedHierarchyWindow.SetExpanded(go.GetInstanceID(), true); } }