private bool IsValidHierarchyInstanceID(int instanceID) { bool isScene = SceneHierarchy.IsSceneHeaderInHierarchyWindow(EditorSceneManager.GetSceneByHandle(instanceID)); bool isGameObject = InternalEditorUtility.GetTypeWithoutLoadingObject(instanceID) == typeof(GameObject); return(isScene || isGameObject); }
internal static void RemoveInvalidActiveParentObjects() { var itemsToRemove = s_ActiveParentObjectPerSceneGUID.Where(activeParent => DetectSceneGuidMismatchInActiveParentState(activeParent)).ToArray(); foreach (var itemToRemove in itemsToRemove) { SceneHierarchy.UpdateSessionStateInfoAndActiveParentObjectValuesForScene(itemToRemove.Key, 0); } }
void OnBeforeSwitchingAwayFromStage(Stage stage) { // Clear parent object for the prefab stage if one was set if (stage is PrefabStage) { SceneHierarchy.SetDefaultParentForSession(stage.GetSceneAt(stage.sceneCount - 1).guid, 0); } stage.SaveHierarchyState(m_SceneHierarchyWindow); }
public static void ClearDefaultParentObject(Scene scene) { if (scene != null) { SceneHierarchy.ClearDefaultParentObject(scene.guid); } else { SceneHierarchy.ClearDefaultParentObject(""); } }
internal void GetActiveParentObjectValuesFromSessionInfo() { for (int i = 0; i < SceneManager.sceneCount; i++) { var key = SceneHierarchy.GetDefaultOriginKeyForScene(SceneManager.GetSceneAt(i).guid); var id = SessionState.GetInt(key, 0); if (id != 0) { activeParentObjects.Add(key, id); } } }
internal void GetActiveParentObjectValuesFromSessionInfo() { for (int i = 0; i < SceneManager.sceneCount; i++) { var key = SceneManager.GetSceneAt(i).guid; var id = SceneHierarchy.GetDefaultParentForSession(SceneManager.GetSceneAt(i).guid); if (id != 0) { s_ActiveParentObjectPerSceneGUID.Add(key, id); } } }
static bool DetectSceneGuidMismatchInActiveParentState(KeyValuePair <string, int> activeParentObject) { var go = EditorUtility.InstanceIDToObject(activeParentObject.Value) as GameObject; if (go != null && go.scene.guid != activeParentObject.Key) { SceneHierarchy.SetDefaultParentForSession(activeParentObject.Key, 0); return(true); } return(false); }
void Awake() { m_HierarchyType = HierarchyType.GameObjects; if (string.IsNullOrEmpty(m_WindowGUID)) { m_WindowGUID = GUID.Generate().ToString(); } if (m_SceneHierarchy == null) { m_SceneHierarchy = new SceneHierarchy(); } m_SceneHierarchy.Awake(this); }
private List <Scene> GetDraggedScenes(List <int> draggedItemIDs) { List <Scene> scenes = new List <Scene>(); foreach (int id in draggedItemIDs) { Scene scene = EditorSceneManager.GetSceneByHandle(id); if (!SceneHierarchy.IsSceneHeaderInHierarchyWindow(scene)) { return(null); } scenes.Add(scene); } return(scenes); }
public static void Group() { GameObject group = new GameObject("Group"); Undo.RegisterCreatedObjectUndo(group, "Group"); if (Selection.gameObjects.Length > 0) { foreach (GameObject gameObject in Selection.gameObjects) { Undo.SetTransformParent(gameObject.transform, group.transform, "Group"); } } Selection.activeGameObject = group; SceneHierarchy.SetExpanded(group, true); }
private static SceneHierarchy PrepareSceneHierarchy(UnityScene scene, bool includeInactive) { var sceneGuid = Guid.NewGuid().ToString(); var res = new SceneHierarchy(sceneGuid, scene.name, MATRIX_IDENTITY); var rootGameObjects = scene.GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { var rootObject = rootGameObjects[i]; if (!includeInactive && !rootObject.activeInHierarchy) { continue; } FillChildrenRecursive(rootObject.transform, res.Children); } return(res); }
internal static void FrameAndRenameNewGameObject() { SceneHierarchyWindow hierarchyWindow = lastInteractedHierarchyWindow; if (hierarchyWindow == null) { return; } SceneHierarchy sceneHierarchy = hierarchyWindow.m_SceneHierarchy; GameObject go = Selection.activeGameObject; if (go != null) { sceneHierarchy.treeView?.Frame(go.GetInstanceID(), true, false); } sceneHierarchy.RenameNewGO(); }
private bool IsValidHierarchyInstanceID(int instanceID) { //Get is persistent without loading object var obj = InternalEditorUtility.GetObjectFromInstanceID(instanceID); if (obj != null ? EditorUtility.IsPersistent(obj) : AssetDatabase.Contains(instanceID)) { return(false); } if (SceneHierarchy.IsSceneHeaderInHierarchyWindow(EditorSceneManager.GetSceneByHandle(instanceID))) { return(true); } if (InternalEditorUtility.GetTypeWithoutLoadingObject(instanceID) == typeof(GameObject)) { return(true); } return(false); }
internal static void FrameAndRenameNewGameObject() { SceneHierarchyWindow hierarchyWindow = GetSceneHierarchyWindowToFocusForNewGameObjects(); if (hierarchyWindow == null) { return; } SceneHierarchy sceneHierarchy = hierarchyWindow.m_SceneHierarchy; GameObject go = Selection.activeGameObject; if (go != null) { sceneHierarchy.treeView?.Frame(go.GetInstanceID(), true, false); } if (s_EnterRenameModeForNewGO.value) { sceneHierarchy.RenameNewGO(); } }
public static void SetDefaultParentObject(GameObject defaultParentObject) { defaultParentObject = !PrefabStageUtility.IsGameObjectThePrefabRootInAnyPrefabStage(defaultParentObject) ? defaultParentObject : null; SceneHierarchy.SetDefaultParentObject(false, defaultParentObject); }
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()); } }
private DragAndDropVisualMode DoDragScenes(GameObjectTreeViewItem parentItem, GameObjectTreeViewItem targetItem, bool perform, DropPosition dropPos) { // We allow dragging SceneAssets on any game object in the Hierarchy to make it easy to drag in a Scene from // the project browser. If dragging on a game object (not a sceneheader) we place the dropped scene // below the game object's scene // Case: 1 List <Scene> scenes = DragAndDrop.GetGenericData(kSceneHeaderDragString) as List <Scene>; bool reorderExistingScenes = (scenes != null); // Case: 2 bool insertNewScenes = false; if (!reorderExistingScenes && DragAndDrop.objectReferences.Length > 0) { int sceneAssetCount = 0; foreach (var dragged in DragAndDrop.objectReferences) { if (dragged is SceneAsset) { sceneAssetCount++; } } insertNewScenes = (sceneAssetCount == DragAndDrop.objectReferences.Length); } // Early out if not case 1 or 2 if (!reorderExistingScenes && !insertNewScenes) { return(DragAndDropVisualMode.None); } if (perform) { List <Scene> scenesToBeMoved = null; if (insertNewScenes) { List <Scene> insertedScenes = new List <Scene>(); foreach (var sceneAsset in DragAndDrop.objectReferences) { string scenePath = AssetDatabase.GetAssetPath(sceneAsset); Scene scene = SceneManager.GetSceneByPath(scenePath); if (SceneHierarchy.IsSceneHeaderInHierarchyWindow(scene)) { m_TreeView.Frame(scene.handle, true, true); } else { bool unloaded = Event.current.alt; if (unloaded) { scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.AdditiveWithoutLoading); } else { scene = EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive); } if (SceneHierarchy.IsSceneHeaderInHierarchyWindow(scene)) { insertedScenes.Add(scene); } } } if (targetItem != null) { scenesToBeMoved = insertedScenes; } // Select added scenes and frame last scene if (insertedScenes.Count > 0) { Selection.instanceIDs = insertedScenes.Select(x => x.handle).ToArray(); m_TreeView.Frame(insertedScenes.Last().handle, true, false); } } else // reorderExistingScenes { scenesToBeMoved = scenes; } if (scenesToBeMoved != null) { if (targetItem != null) { Scene dstScene = targetItem.scene; if (SceneHierarchy.IsSceneHeaderInHierarchyWindow(dstScene)) { if (!targetItem.isSceneHeader || dropPos == DropPosition.Upon) { dropPos = DropPosition.Below; } if (dropPos == DropPosition.Above) { for (int i = 0; i < scenesToBeMoved.Count; i++) { EditorSceneManager.MoveSceneBefore(scenesToBeMoved[i], dstScene); } } else if (dropPos == DropPosition.Below) { for (int i = scenesToBeMoved.Count - 1; i >= 0; i--) { EditorSceneManager.MoveSceneAfter(scenesToBeMoved[i], dstScene); } } } } else { Scene dstScene = SceneManager.GetSceneAt(SceneManager.sceneCount - 1); for (int i = scenesToBeMoved.Count - 1; i >= 0; i--) { EditorSceneManager.MoveSceneAfter(scenesToBeMoved[i], dstScene); } } } } return(DragAndDropVisualMode.Move); }
internal bool SwitchToStage(Stage stage, bool setAsFirstItemAfterMainStage, Analytics.ChangeType changeTypeAnalytics) { if (stage == null) { Debug.LogError("Cannot switch to new stage. Input stage is null"); return(false); } bool setPreviousSelection = stage.opened; StopAnimationPlaybackAndPreviewing(); Stage previousStage = currentStage; if (!previousStage.AskUserToSaveModifiedStageBeforeSwitchingStage()) { // User canceled switching stage. // If the history contains the new stage we do not destroy it (the user // can have clicked a previous stage in the breadcrumb bar). if (!stageHistory.Contains(stage)) { DestroyImmediate(stage); } return(false); } // User accepted to switch stage (and lose any data if not saved) // Clear parent object for the prefab stage if one was set if (previousStage.GetType() == typeof(PrefabStage)) { SessionState.SetInt(SceneHierarchy.GetDefaultOriginKeyForScene(previousStage.GetSceneAt(previousStage.sceneCount - 1).guid), 0); } // Here we save current Hierarchy and SceneView stage state beforeSwitchingAwayFromStage?.Invoke(previousStage); // Used by the Avatar Editor to exit its editing mode before opening new stage stageChanging?.Invoke(previousStage, stage); // Set/Add stage in m_NavigationHistory (and detect what stages should be removed) if (m_DebugLogging) { Debug.Log("Set Navigation History (setAsFirstItemAfterMainStage " + setAsFirstItemAfterMainStage); } var deleteStages = new List <Stage>(); if (setAsFirstItemAfterMainStage) { deleteStages = m_NavigationHistory.ClearHistory(); m_NavigationHistory.AddStage(stage); } else { if (m_NavigationHistory.TrySetToIndexOfItem(stage)) { deleteStages = m_NavigationHistory.ClearForwardHistoryAfterCurrentStage(); } else { deleteStages = m_NavigationHistory.ClearForwardHistoryAndAddItem(stage); } } m_Analytics.ChangingStageStarted(previousStage); if (m_DebugLogging) { Debug.Log("Activate new stage"); } // Activate stage after setting up the history above so objects loaded during ActivateStage can query current stage bool success; try { if (!stage.opened) { stage.opened = true; success = stage.OnOpenStage(); } else { stage.OnReturnToStage(); success = stage.isValid; } if (success) { if (m_DebugLogging) { Debug.Log("Deactivate previous stage"); } // Here the Hierarchy and SceneView sync's up to the new stage stage.setSelectionAndScrollWhenBecomingCurrentStage = setPreviousSelection; stageChanged?.Invoke(previousStage, stage); } } catch (Exception e) { success = false; Debug.LogError("Error while changing Stage: " + e); } if (success) { // Activation and changing stage succeeded. Now destroy removed stages if (m_DebugLogging) { Debug.Log("Destroying " + deleteStages.Count + " stages"); } // A previous existing stage can have been requested to set as the current so don't delete that deleteStages.Remove(stage); DeleteStagesInReverseOrder(deleteStages); // Here we update state that relies on old scenes having been destroyed entirely. afterSuccessfullySwitchedToStage?.Invoke(stage); m_Analytics.ChangingStageEnded(stage, changeTypeAnalytics); } else { if (m_DebugLogging) { Debug.Log("Switching stage failed (" + stage + ")"); } RecoverFromStageChangeError(previousStage, deleteStages); } return(success); }
public SceneHierarchyStageHandling(SceneHierarchyWindow sceneHierarchyWindow) { m_SceneHierarchyWindow = sceneHierarchyWindow; m_SceneHierarchy = sceneHierarchyWindow.sceneHierarchy; }
public static void ClearDefaultParentObject() { SceneHierarchy.ClearDefaultParentObject(); }