internal static SceneTemplateAsset CreateTemplateFromScene(SceneAsset sourceSceneAsset, string sceneTemplatePath, SceneTemplateAnalytics.TemplateCreationType creationType) { var sourceScenePath = sourceSceneAsset == null ? null : AssetDatabase.GetAssetPath(sourceSceneAsset); if (sourceSceneAsset != null && sourceScenePath != null && String.IsNullOrEmpty(sceneTemplatePath)) { var newSceneAssetName = $"{Path.GetFileNameWithoutExtension(sourceScenePath)}.{SceneTemplateAsset.extension}"; sceneTemplatePath = Path.Combine(Path.GetDirectoryName(sourceScenePath), newSceneAssetName).Replace("\\", "/"); sceneTemplatePath = AssetDatabase.GenerateUniqueAssetPath(sceneTemplatePath); } if (string.IsNullOrEmpty(sceneTemplatePath)) { throw new Exception("No path specified for new Scene template"); } var sceneTemplate = ScriptableObject.CreateInstance <SceneTemplateAsset>(); AssetDatabase.CreateAsset(sceneTemplate, sceneTemplatePath); if (!String.IsNullOrEmpty(sourceScenePath)) { if (SceneManager.GetActiveScene().path == sourceScenePath && SceneManager.GetActiveScene().isDirty) { EditorSceneManager.SaveScene(SceneManager.GetActiveScene()); } sceneTemplate.BindScene(sourceSceneAsset); } EditorUtility.SetDirty(sceneTemplate); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(sceneTemplatePath); var sceneCreationEvent = new SceneTemplateAnalytics.SceneTemplateCreationEvent(sceneTemplate, creationType); SceneTemplateAnalytics.SendSceneTemplateCreationEvent(sceneCreationEvent); SceneTemplateUtils.SetLastFolder(sceneTemplatePath); Selection.SetActiveObjectWithContext(sceneTemplate, null); return(sceneTemplate); }
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)); }
internal static System.Tuple <Scene, SceneAsset> Instantiate(SceneTemplateAsset sceneTemplate, bool loadAdditively, string newSceneOutputPath, SceneTemplateAnalytics.SceneInstantiationType instantiationType) { if (!sceneTemplate.IsValid) { throw new Exception("templateScene is empty"); } 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.dependencies.Any(dep => dep.instantiationMode == TemplateInstantiationMode.Clone); SceneAsset newSceneAsset = null; Scene newScene; var templatePipeline = sceneTemplate.CreatePipeline(); if (hasAnyCloneableDependencies) { if (!InstantiateScene(sceneTemplate, sourceScenePath, ref newSceneOutputPath)) { instantiateEvent.isCancelled = true; SceneTemplateAnalytics.SendSceneInstantiationEvent(instantiateEvent); return(null); } templatePipeline?.BeforeTemplateInstantiation(sceneTemplate, loadAdditively, newSceneOutputPath); newSceneTemplateInstantiating?.Invoke(sceneTemplate, newSceneOutputPath, loadAdditively); var refPathMap = new Dictionary <string, string>(); var refMap = CopyCloneableDependencies(sceneTemplate, newSceneOutputPath, ref refPathMap); newScene = EditorSceneManager.OpenScene(newSceneOutputPath, loadAdditively ? OpenSceneMode.Additive : OpenSceneMode.Single); newSceneAsset = AssetDatabase.LoadAssetAtPath <SceneAsset>(newSceneOutputPath); var idMap = new Dictionary <int, int>(); idMap.Add(sceneTemplate.templateScene.GetInstanceID(), newSceneAsset.GetInstanceID()); EditorSceneManager.RemapAssetReferencesInScene(newScene, refPathMap, idMap); EditorSceneManager.SaveScene(newScene, newSceneOutputPath); foreach (var clone in refMap.Values) { if (clone) { EditorUtility.SetDirty(clone); } } AssetDatabase.SaveAssets(); } else { templatePipeline?.BeforeTemplateInstantiation(sceneTemplate, loadAdditively, newSceneOutputPath); newSceneTemplateInstantiating?.Invoke(sceneTemplate, newSceneOutputPath, loadAdditively); if (loadAdditively) { newScene = EditorSceneManager.OpenScene(sourceScenePath, OpenSceneMode.Additive); } else { newScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); var sourceScene = EditorSceneManager.OpenScene(sourceScenePath, OpenSceneMode.Additive); SceneManager.MergeScenes(sourceScene, newScene); } } SceneTemplateAnalytics.SendSceneInstantiationEvent(instantiateEvent); templatePipeline?.AfterTemplateInstantiation(sceneTemplate, newScene, loadAdditively, newSceneOutputPath); newSceneTemplateInstantiated?.Invoke(sceneTemplate, newScene, newSceneAsset, loadAdditively); SceneTemplateUtils.SetLastFolder(newSceneOutputPath); return(new System.Tuple <Scene, SceneAsset>(newScene, newSceneAsset)); }