Exemplo n.º 1
0
        static void HandleSceneSave(Scene scene)
        {
            {
                var result = scene.path;

                var directory          = Path.GetDirectoryName(result);
                var filenameWithoutExt = Path.GetFileNameWithoutExtension(result);

                if (s_CurrentInMemorySceneState.hasCloneableDependencies)
                {
                    var oldDependencyFolder = Path.Combine(s_CurrentInMemorySceneState.rootFolder, s_CurrentInMemorySceneState.dependencyFolderName);
                    var newDependencyFolder = Path.Combine(directory, filenameWithoutExt);
                    if (Directory.Exists(newDependencyFolder))
                    {
                        SceneTemplateUtils.DeleteAsset(newDependencyFolder);
                    }
                    var errorMsg = AssetDatabase.MoveAsset(oldDependencyFolder, newDependencyFolder);
                    if (!string.IsNullOrEmpty(errorMsg))
                    {
                        Debug.LogError(errorMsg);
                        return;
                    }
                }

                SceneTemplateUtils.DeleteAsset(s_CurrentInMemorySceneState.rootFolder);

                var success = EditorSceneManager.ReloadScene(scene);
                if (!success)
                {
                    Debug.LogError($"Failed to reload scene {scene.path}");
                }

                ClearInMemorySceneState();
            }
        }
Exemplo n.º 2
0
        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 (hasAnyCloneableDependencies || loadAdditively)
            {
                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 refMap = CopyCloneableDependencies(sceneTemplate, newSceneOutputPath, ref refPathMap);
                    idMap.Add(sceneTemplate.templateScene.GetInstanceID(), newSceneAsset.GetInstanceID());
                    ReferenceUtils.RemapAssetReferences(refPathMap, idMap);

                    foreach (var clone in refMap.Values)
                    {
                        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);
                }
            }
            else
            {
                var needTempSceneCleanup = false;
                if (SceneTemplateUtils.IsAssetReadOnly(sourceScenePath))
                {
                    sourceScenePath      = CopyToTemporaryScene(sourceScenePath);
                    needTempSceneCleanup = true;
                }

                templatePipeline?.BeforeTemplateInstantiation(sceneTemplate, loadAdditively, newSceneOutputPath);
                newSceneTemplateInstantiating?.Invoke(sceneTemplate, newSceneOutputPath, loadAdditively);
                newScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
                var sourceScene = EditorSceneManager.OpenScene(sourceScenePath, OpenSceneMode.Additive);
                SceneManager.MergeScenes(sourceScene, newScene);

                if (!string.IsNullOrEmpty(newSceneOutputPath))
                {
                    EditorSceneManager.SaveScene(newScene, newSceneOutputPath);
                }

                if (needTempSceneCleanup)
                {
                    SceneTemplateUtils.DeleteAsset(sourceScenePath);
                }
            }

            SceneTemplateAnalytics.SendSceneInstantiationEvent(instantiateEvent);
            templatePipeline?.AfterTemplateInstantiation(sceneTemplate, newScene, loadAdditively, newSceneOutputPath);
            newSceneTemplateInstantiated?.Invoke(sceneTemplate, newScene, newSceneAsset, loadAdditively);

            SceneTemplateUtils.SetLastFolder(newSceneOutputPath);

            return(new InstantiationResult(newScene, newSceneAsset));
        }