internal static void Place(GameObject go, GameObject parent) { Transform defaultObjectTransform = SceneView.GetDefaultParentObjectIfSet(); if (parent != null) { SetGameObjectParent(go, parent.transform); } else if (defaultObjectTransform != null) { 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 { 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); EditorWindow.FocusWindowIfItsOpen <SceneHierarchyWindow>(); Selection.activeGameObject = go; }
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 bool DragPerform(SceneView sceneView, GameObject draggedObject, GameObject go) { var stage = StageNavigationManager.instance.currentStage; if (stage is PrefabStage) { var prefabAssetThatIsAddedTo = AssetDatabase.LoadMainAssetAtPath(stage.assetPath); if (PrefabUtility.CheckIfAddingPrefabWouldResultInCyclicNesting(prefabAssetThatIsAddedTo, go)) { PrefabUtility.ShowCyclicNestingWarningDialog(); return(false); } } var defaultParentObject = SceneView.GetDefaultParentObjectIfSet(); var parent = defaultParentObject != null ? defaultParentObject : sceneView.customParentForDraggedObjects; string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent, draggedObject.name); if (parent != null) { draggedObject.transform.parent = parent; } draggedObject.hideFlags = 0; Undo.RegisterCreatedObjectUndo(draggedObject, "Place " + draggedObject.name); EditorUtility.SetDirty(draggedObject); DragAndDrop.AcceptDrag(); Selection.activeObject = draggedObject; HandleUtility.ignoreRaySnapObjects = null; if (SceneView.mouseOverWindow != null) { SceneView.mouseOverWindow.Focus(); } if (!Application.IsPlaying(draggedObject)) { draggedObject.name = uniqueName; } return(true); }
internal static void DragPerform(SceneView sceneView, GameObject draggedObject, GameObject go) { var defaultParentObject = SceneView.GetDefaultParentObjectIfSet(); var parent = defaultParentObject != null ? defaultParentObject : sceneView.customParentForDraggedObjects; string uniqueName = GameObjectUtility.GetUniqueNameForSibling(parent, draggedObject.name); if (parent != null) { draggedObject.transform.parent = parent; } draggedObject.hideFlags = 0; Undo.RegisterCreatedObjectUndo(draggedObject, "Place " + draggedObject.name); EditorUtility.SetDirty(draggedObject); DragAndDrop.AcceptDrag(); if (s_ShouldClearSelection) { Selection.objects = new[] { draggedObject }; s_ShouldClearSelection = false; } else { // Since this inspector code executes for each dragged GameObject we should retain // selection to all of them by joining them to the previous selection list Selection.objects = Selection.gameObjects.Union(new[] { draggedObject }).ToArray(); } HandleUtility.ignoreRaySnapObjects = null; if (SceneView.mouseOverWindow != null) { SceneView.mouseOverWindow.Focus(); } if (!Application.IsPlaying(draggedObject)) { draggedObject.name = uniqueName; } s_CyclicNestingDetected = false; }
public static void HandleSpriteSceneDrag(SceneView sceneView, IEvent evt, Object[] objectReferences, string[] paths, ShowFileDialogDelegate saveFileDialog) { if (evt.type != EventType.DragUpdated && evt.type != EventType.DragPerform && evt.type != EventType.DragExited) { return; } // Return if any of the dragged objects are null, e.g. a MonoBehaviour without a managed instance if (objectReferences.Any(obj => obj == null)) { return; } // Regardless of EditorBehaviorMode or SceneView mode we don't handle if texture is dragged over a GO with renderer if (objectReferences.Length == 1 && objectReferences[0] as UnityTexture2D != null) { GameObject go = HandleUtility.PickGameObject(evt.mousePosition, true); if (go != null) { var renderer = go.GetComponent <Renderer>(); if (renderer != null && !(renderer is SpriteRenderer)) { // There is an object where the cursor is // and we are dragging a texture. Most likely user wants to // assign texture to the GO // Case 730444: Proceed only if the go has a renderer CleanUp(true); return; } } } switch (evt.type) { case (EventType.DragUpdated): DragType newDragType = evt.alt ? DragType.CreateMultiple : DragType.SpriteAnimation; if (s_DragType != newDragType || s_SceneDragObjects == null) // Either this is first time we are here OR evt.alt changed during drag { if (!ExistingAssets(objectReferences) && PathsAreValidTextures(paths)) // External drag with images that are not in the project { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; s_SceneDragObjects = new List <Object>(); s_DragType = newDragType; } else // Internal drag with assets from project { List <Sprite> assets = GetSpriteFromPathsOrObjects(objectReferences, paths, evt.type); if (assets.Count == 0) { return; } if (s_DragType != DragType.NotInitialized) // evt.alt changed during drag, so we need to cleanup and start over { CleanUp(true); } s_DragType = newDragType; CreateSceneDragObjects(assets, sceneView); IgnoreForRaycasts(s_SceneDragObjects); } } PositionSceneDragObjects(s_SceneDragObjects, sceneView, evt.mousePosition); DragAndDrop.visualMode = DragAndDropVisualMode.Copy; evt.Use(); break; case (EventType.DragPerform): List <Sprite> sprites = GetSpriteFromPathsOrObjects(objectReferences, paths, evt.type); if (sprites.Count > 0 && s_SceneDragObjects != null) { // Store current undoIndex to undo all operations done if any part of sprite creation fails int undoIndex = Undo.GetCurrentGroup(); // For external drags, we have delayed all creation to DragPerform because only now we have the imported sprite assets if (s_SceneDragObjects.Count == 0) { CreateSceneDragObjects(sprites, sceneView); PositionSceneDragObjects(s_SceneDragObjects, sceneView, evt.mousePosition); } foreach (GameObject dragGO in s_SceneDragObjects) { dragGO.hideFlags = HideFlags.None; // When in e.g Prefab Mode ensure to reparent dragged objects under the prefab root Transform defaultObjectTransform = SceneView.GetDefaultParentObjectIfSet(); if (defaultObjectTransform != null) { dragGO.transform.SetParent(defaultObjectTransform, true); } else if (sceneView.customParentForDraggedObjects != null) { dragGO.transform.SetParent(sceneView.customParentForDraggedObjects, true); } Undo.RegisterCreatedObjectUndo(dragGO, "Create Sprite"); EditorUtility.SetDirty(dragGO); } bool createGameObject = true; if (s_DragType == DragType.SpriteAnimation && sprites.Count > 1) { createGameObject = AddAnimationToGO((GameObject)s_SceneDragObjects[0], sprites.ToArray(), saveFileDialog); } if (createGameObject) { Selection.objects = s_SceneDragObjects.ToArray(); } else { // Revert all Create Sprite actions if animation failed to be created or was cancelled Undo.RevertAllDownToGroup(undoIndex); } CleanUp(!createGameObject); evt.Use(); } break; case EventType.DragExited: if (s_SceneDragObjects != null) { CleanUp(true); evt.Use(); } break; } }
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()); } }