internal static InstantiationResult Instantiate(SceneTemplateAsset sceneTemplate, bool loadAdditively, string newSceneOutputPath, SceneTemplateAnalytics.SceneInstantiationType instantiationType) { if (!sceneTemplate.isValid) { throw new Exception("templateScene is empty"); } if (EditorApplication.isUpdating) { Debug.LogFormat(LogType.Warning, LogOption.None, null, "Cannot instantiate a new scene while updating the editor is disallowed."); return(null); } // If we are loading additively, we cannot add a new Untitled scene if another unsaved Untitled scene is already opened if (loadAdditively && SceneTemplateUtils.HasSceneUntitled()) { Debug.LogFormat(LogType.Warning, LogOption.None, null, "Cannot instantiate a new scene additively while an unsaved Untitled scene already exists."); return(null); } var sourceScenePath = AssetDatabase.GetAssetPath(sceneTemplate.templateScene); if (String.IsNullOrEmpty(sourceScenePath)) { throw new Exception("Cannot find path for sceneTemplate: " + sceneTemplate.ToString()); } if (!Application.isBatchMode && !loadAdditively && !EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo()) { return(null); } var instantiateEvent = new SceneTemplateAnalytics.SceneInstantiationEvent(sceneTemplate, instantiationType) { additive = loadAdditively }; sceneTemplate.UpdateDependencies(); var hasAnyCloneableDependencies = sceneTemplate.hasCloneableDependencies; SceneAsset newSceneAsset = null; Scene newScene; var templatePipeline = sceneTemplate.CreatePipeline(); if (!InstantiateInMemoryScene(sceneTemplate, sourceScenePath, ref newSceneOutputPath, out var rootFolder, out var isTempMemory)) { instantiateEvent.isCancelled = true; SceneTemplateAnalytics.SendSceneInstantiationEvent(instantiateEvent); return(null); } templatePipeline?.BeforeTemplateInstantiation(sceneTemplate, loadAdditively, isTempMemory ? null : newSceneOutputPath); newSceneTemplateInstantiating?.Invoke(sceneTemplate, isTempMemory ? null : newSceneOutputPath, loadAdditively); newSceneAsset = AssetDatabase.LoadAssetAtPath <SceneAsset>(newSceneOutputPath); var refPathMap = new Dictionary <string, string>(); var idMap = new Dictionary <int, int>(); if (hasAnyCloneableDependencies) { var clonedAssets = CopyCloneableDependencies(sceneTemplate, newSceneOutputPath, ref refPathMap); idMap.Add(sceneTemplate.templateScene.GetInstanceID(), newSceneAsset.GetInstanceID()); ReferenceUtils.RemapAssetReferences(refPathMap, idMap); foreach (var clone in clonedAssets) { if (clone) { EditorUtility.SetDirty(clone); } } AssetDatabase.SaveAssets(); } newScene = EditorSceneManager.OpenScene(newSceneOutputPath, loadAdditively ? OpenSceneMode.Additive : OpenSceneMode.Single); if (hasAnyCloneableDependencies) { EditorSceneManager.RemapAssetReferencesInScene(newScene, refPathMap, idMap); } EditorSceneManager.SaveScene(newScene, newSceneOutputPath); if (isTempMemory) { newSceneAsset = null; newScene.SetPathAndGuid("", newScene.guid); s_CurrentInMemorySceneState.guid = newScene.guid; s_CurrentInMemorySceneState.rootFolder = rootFolder; s_CurrentInMemorySceneState.hasCloneableDependencies = hasAnyCloneableDependencies; s_CurrentInMemorySceneState.dependencyFolderName = Path.GetFileNameWithoutExtension(newSceneOutputPath); } SceneTemplateAnalytics.SendSceneInstantiationEvent(instantiateEvent); templatePipeline?.AfterTemplateInstantiation(sceneTemplate, newScene, loadAdditively, newSceneOutputPath); newSceneTemplateInstantiated?.Invoke(sceneTemplate, newScene, newSceneAsset, loadAdditively); SceneTemplateUtils.SetLastFolder(newSceneOutputPath); return(new InstantiationResult(newScene, newSceneAsset)); }
private void BuildUI() { // Keyboard events need a focusable element to trigger rootVisualElement.focusable = true; rootVisualElement.RegisterCallback <KeyUpEvent>(e => { switch (e.keyCode) { case KeyCode.Escape when !docked: Close(); break; } }); // Load stylesheets rootVisualElement.AddToClassList(Styles.unityThemeVariables); rootVisualElement.AddToClassList(Styles.sceneTemplateThemeVariables); rootVisualElement.AddStyleSheetPath(Styles.k_CommonStyleSheetPath); rootVisualElement.AddStyleSheetPath(Styles.variableStyleSheet); // Create a container to offset everything nicely inside the window { var offsetContainer = new VisualElement(); offsetContainer.AddToClassList(Styles.classOffsetContainer); rootVisualElement.Add(offsetContainer); // Create a container for the scene templates and description { var mainContainer = new VisualElement(); mainContainer.style.flexDirection = FlexDirection.Row; mainContainer.AddToClassList(Styles.classMainContainer); offsetContainer.Add(mainContainer); { // Create a container for the scene templates lists(left side) var sceneTemplatesContainer = new VisualElement(); sceneTemplatesContainer.AddToClassList(Styles.classTemplatesContainer); sceneTemplatesContainer.AddToClassList(Styles.sceneTemplateDialogBorder); // mainContainer.Add(sceneTemplatesContainer); CreateAllSceneTemplateListsUI(sceneTemplatesContainer); // Create a container for the template description (right side) var descriptionContainer = new VisualElement(); descriptionContainer.AddToClassList(Styles.classDescriptionContainer); descriptionContainer.AddToClassList(Styles.classBorder); // mainContainer.Add(descriptionContainer); CreateTemplateDescriptionUI(descriptionContainer); if (EditorPrefs.HasKey(GetKeyName(nameof(m_Splitter)))) { var splitterPosition = EditorPrefs.GetFloat(GetKeyName(nameof(m_Splitter))); sceneTemplatesContainer.style.width = splitterPosition; } else { EditorApplication.delayCall += () => { sceneTemplatesContainer.style.width = position.width * 0.60f; }; } m_Splitter = new VisualSplitter(sceneTemplatesContainer, descriptionContainer, FlexDirection.Row); mainContainer.Add(m_Splitter); } } // Create the button row { var buttonRow = new VisualElement(); buttonRow.AddToClassList(Styles.sceneTemplateDialogFooter); offsetContainer.Add(buttonRow); buttonRow.style.flexDirection = FlexDirection.Row; var loadAdditiveToggle = new Toggle() { name = k_SceneTemplateCreateAdditiveButtonName, text = L10n.Tr("Load additively"), tooltip = k_LoadAdditivelyToolTip }; if (SceneTemplateUtils.HasSceneUntitled()) { loadAdditiveToggle.SetEnabled(false); loadAdditiveToggle.tooltip = k_LoadAdditivelyToolTipDisabledHasUnsavedUntitled; } buttonRow.Add(loadAdditiveToggle); { // The buttons need to be right-aligned var buttonSection = new VisualElement(); buttonSection.style.flexDirection = FlexDirection.RowReverse; buttonSection.AddToClassList(Styles.classButtons); buttonRow.Add(buttonSection); var createSceneButton = new Button(() => { if (m_LastSelectedTemplate == null) { return; } OnCreateNewScene(m_LastSelectedTemplate); }) { text = L10n.Tr("Create"), tooltip = L10n.Tr("Instantiate a new scene from a template") }; createSceneButton.AddToClassList(Styles.classButton); var cancelButton = new Button(Close) { text = L10n.Tr("Cancel"), tooltip = L10n.Tr("Close scene template dialog without instantiating a new scene.") }; cancelButton.AddToClassList(Styles.classButton); buttonSection.Add(cancelButton); buttonSection.Add(createSceneButton); m_Buttons = new List <ButtonInfo> { new ButtonInfo { button = createSceneButton, callback = OnCreateNewScene }, new ButtonInfo { button = cancelButton, callback = info => Close() } }; m_SelectedButtonIndex = m_Buttons.FindIndex(bi => bi.button == createSceneButton); UpdateSelectedButton(); } } SetAllElementSequentiallyFocusable(rootVisualElement, false); } if (m_LastSelectedTemplate != null) { UpdateTemplateDescriptionUI(m_LastSelectedTemplate); } }