internal static void Place(GameObject go, GameObject parent, bool ignoreSceneViewPosition = true) { Transform defaultObjectTransform = SceneView.GetDefaultParentObjectIfSet(); if (parent != null) { // At this point, RecordStructureChange is already ongoing (from the CreatePrimitive call through the CreateAndPlacePrimitive method). We need to flush the stack to finalise the RecordStructureChange before the // following SetTransformParent call takes place. Undo.FlushTrackedObjects(); SetGameObjectParent(go, parent.transform); } else if (defaultObjectTransform != null) { // At this point, RecordStructureChange is already ongoing (from the CreatePrimitive call through the CreateAndPlacePrimitive method). We need to flush the stack to finalise the RecordStructureChange before the // following SetTransformParent call takes place. Undo.FlushTrackedObjects(); SetGameObjectParent(go, defaultObjectTransform); } else { // When creating a 3D object without a parent, this option puts it at the world origin instead of scene pivot. if (placeObjectsAtWorldOrigin) { go.transform.position = Vector3.zero; } else if (ignoreSceneViewPosition) { SceneView.PlaceGameObjectInFrontOfSceneView(go); } StageUtility.PlaceGameObjectInCurrentStage(go); // may change parent } // Only at this point do we know the actual parent of the object and can modify its name accordingly. GameObjectUtility.EnsureUniqueNameForSibling(go); Undo.SetCurrentGroupName("Create " + go.name); var sh = SceneHierarchyWindow.GetSceneHierarchyWindowToFocusForNewGameObjects(); if (sh != null) { sh.Focus(); } Selection.activeGameObject = go; }
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()); } }