internal void NavigateBack(Analytics.ChangeType stageChangeAnalytics) { if (m_NavigationHistory.CanGoBackward()) { var previousStage = m_NavigationHistory.GetPrevious(); SwitchToStage(previousStage, false, true, stageChangeAnalytics); } }
internal void GoToMainStage(bool setPreviousSelection, Analytics.ChangeType stageChangeAnalytics) { if (currentItem.isMainStage) { return; } SwitchToStage(m_NavigationHistory.GetOrCreateMainStage(), false, setPreviousSelection, stageChangeAnalytics); }
internal void GoToMainStage(Analytics.ChangeType stageChangeAnalytics) { if (currentStage is MainStage) { return; } SwitchToStage(m_NavigationHistory.GetMainStage(), false, stageChangeAnalytics); }
public void ChangingStageEnded(StageNavigationItem newStageItem, Analytics.ChangeType changeTypeAnalytics) { m_EventData.changeType = changeTypeAnalytics; m_EventData.newStage = GetStageType(newStageItem); m_EventData.newBreadcrumbCount = StageNavigationManager.instance.stageHistory.Length; m_EventData.autoSaveEnabled = StageNavigationManager.instance.autoSave; var duration = DateTime.UtcNow.Subtract(m_StartedTime); UsabilityAnalytics.SendEvent("stageChange", m_StartedTime, duration, true, m_EventData); }
internal PrefabStage OpenPrefabMode(string prefabAssetPath, GameObject instanceRoot, Analytics.ChangeType changeTypeAnalytics) { if (EditorApplication.isPlaying) { bool blockPrefabModeInPlaymode = CheckIfAnyComponentShouldBlockPrefabModeInPlayMode(prefabAssetPath); if (blockPrefabModeInPlaymode) { return(null); } } PrefabStage prefabStage = GetCurrentPrefabStage(); bool setAsFirstItemAfterMainStage = prefabStage == null || !IsPartOfPrefabStage(instanceRoot, prefabStage); var previousSelection = Selection.activeGameObject; UInt64 previousFileID = (instanceRoot != null) ? GetFileIDForCorrespondingObjectFromSourceAtPath(previousSelection, prefabAssetPath) : 0; if (SwitchToStage(m_NavigationHistory.GetOrCreatePrefabStage(prefabAssetPath), setAsFirstItemAfterMainStage, false, changeTypeAnalytics)) { // If selection did not change by switching stage (by us or user) then handle automatic selection in new prefab mode if (Selection.activeGameObject == previousSelection) { HandleSelectionWhenSwithingToNewPrefabMode(GetCurrentPrefabStage().prefabContentsRoot, previousFileID); } var newPrefabStage = m_PrefabStages.Last(); Assert.IsTrue(newPrefabStage.prefabAssetPath == prefabAssetPath); SceneView.RepaintAll(); return(newPrefabStage); } else { // Failed to switch to new stage return(null); } }
void OnStageSwitched(StageNavigationItem newStage, bool setAsFirstItemAfterMainStage, Analytics.ChangeType changeTypeAnalytics) { var previousStage = currentItem; if (setAsFirstItemAfterMainStage) { m_NavigationHistory.ClearHistory(); m_NavigationHistory.AddItem(newStage); } else { if (m_NavigationHistory.TrySetToIndexOfItem(newStage)) { m_NavigationHistory.ClearForwardHistoryAfterCurrentStage(); } else { m_NavigationHistory.ClearForwardHistoryAndAddItem(newStage); } } if (stageChanged != null) { stageChanged(previousStage, newStage); } m_Analytics.ChangingStageEnded(newStage, changeTypeAnalytics); }
internal bool SwitchToStage(StageNavigationItem newStage, bool setAsFirstItemAfterMainStage, bool setPreviousSelection, Analytics.ChangeType changeTypeAnalytics) { if (newStage.isPrefabStage && !newStage.prefabAssetExists) { Debug.LogError("Cannot switch to new stage! Prefab asset does not exist: " + (!string.IsNullOrEmpty(newStage.prefabAssetPath) ? newStage.prefabAssetPath : newStage.prefabAssetGUID)); { return(false); } } StopAnimationPlaybackAndPreviewing(); // Close current stage (returns false if user cancels closing prefab scene) if (!CleanupCurrentStageBeforeSwitchingStage()) { return(false); } newStage.setSelectionAndScrollWhenBecomingCurrentStage = setPreviousSelection; if (stageChanging != null) { stageChanging(currentItem, newStage); } // Switch to new stage. if (!newStage.isMainStage) { // Create prefab stage and add it to the list of Prefab stages before loading the prefab contents so the // user callbacks Awake and OnEnable are able to query the current prefab stage PrefabStage prefabStage = new PrefabStage(); m_PrefabStages.Add(prefabStage); var success = prefabStage.OpenStage(newStage.prefabAssetPath); if (!success) { m_PrefabStages.RemoveAt(m_PrefabStages.Count - 1); return(false); } } // Set new stage after we allowed the user to cancel changing stage OnStageSwitched(newStage, setAsFirstItemAfterMainStage, changeTypeAnalytics); return(true); }
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); } if (stage.isAssetMissing) { Debug.LogError($"Cannot switch to new stage. Asset does not exist so stage cannot be reconstructed: {stage.assetPath}"); DestroyImmediate(stage); 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) // 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.OpenStage(); } else { 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); }