예제 #1
0
        internal bool UpdateDependencies()
        {
            if (!isValid)
            {
                dependencies = new DependencyInfo[0];
                return(false);
            }

            var scenePath = AssetDatabase.GetAssetPath(templateScene.GetInstanceID());

            if (string.IsNullOrEmpty(scenePath))
            {
                dependencies = new DependencyInfo[0];
                return(false);
            }

            var sceneName   = Path.GetFileNameWithoutExtension(scenePath);
            var sceneFolder = Path.GetDirectoryName(scenePath).Replace("\\", "/");
            var sceneCloneableDependenciesFolder = Path.Combine(sceneFolder, sceneName).Replace("\\", "/");

            var depList = new List <Object>();

            ReferenceUtils.GetSceneDependencies(scenePath, depList);

            var newDependenciesAdded = false;

            dependencies = depList.Select(d =>
            {
                var oldDependencyInfo = dependencies.FirstOrDefault(di => di.dependency.GetInstanceID() == d.GetInstanceID());
                if (oldDependencyInfo != null)
                {
                    return(oldDependencyInfo);
                }

                newDependenciesAdded = true;

                var depTypeInfo       = SceneTemplateProjectSettings.Get().GetDependencyInfo(d);
                var dependencyPath    = AssetDatabase.GetAssetPath(d);
                var instantiationMode = depTypeInfo.defaultInstantiationMode;
                if (depTypeInfo.supportsModification && !string.IsNullOrEmpty(dependencyPath))
                {
                    var assetFolder = Path.GetDirectoryName(dependencyPath).Replace("\\", "/");
                    if (assetFolder == sceneCloneableDependenciesFolder)
                    {
                        instantiationMode = TemplateInstantiationMode.Clone;
                    }
                }

                return(new DependencyInfo()
                {
                    dependency = d,
                    instantiationMode = instantiationMode
                });
            }).ToArray();

            var isAssetReadOnly = SceneTemplateUtils.IsAssetReadOnly(scenePath);

            if (newDependenciesAdded && !isAssetReadOnly)
            {
                EditorUtility.SetDirty(this);
                AssetDatabase.SaveAssets();
            }

            return(newDependenciesAdded);
        }
예제 #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));
        }