Пример #1
0
        private static List <SceneTemplateInfo> GetSceneTemplateInfos()
        {
            var sceneTemplateList = new List <SceneTemplateInfo>();

            // Add the special Empty and Basic template
            s_EmptySceneTemplateInfo.isPinned = SceneTemplateProjectSettings.Get().GetPinState(s_EmptySceneTemplateInfo.name);
            s_BasicSceneTemplateInfo.isPinned = SceneTemplateProjectSettings.Get().GetPinState(s_BasicSceneTemplateInfo.name);

            // Check for real templateAssets:
            var sceneTemplateAssetInfos = SceneTemplateUtils.GetSceneTemplatePaths().Select(templateAssetPath =>
            {
                var sceneTemplateAsset = AssetDatabase.LoadAssetAtPath <SceneTemplateAsset>(templateAssetPath);
                return(Tuple.Create(templateAssetPath, sceneTemplateAsset));
            })
                                          .Where(templateData => {
                if (templateData.Item2 == null)
                {
                    return(false);
                }
                if (!templateData.Item2.IsValid)
                {
                    return(false);
                }
                var pipeline = templateData.Item2.CreatePipeline();
                if (pipeline == null)
                {
                    return(true);
                }
                return(pipeline.IsValidTemplateForInstantiation(templateData.Item2));
            }).
                                          Select(templateData =>
            {
                var assetName = Path.GetFileNameWithoutExtension(templateData.Item1);

                var isReadOnly = false;
                if (templateData.Item1.StartsWith("Packages/") && AssetDatabase.GetAssetFolderInfo(templateData.Item1, out var isRootFolder, out var isImmutable))
                {
                    isReadOnly = isImmutable;
                }

                return(new SceneTemplateInfo {
                    name = string.IsNullOrEmpty(templateData.Item2.templateName) ? assetName : templateData.Item2.templateName,
                    isPinned = templateData.Item2.addToDefaults,
                    isReadonly = isReadOnly,
                    assetPath = templateData.Item1,
                    description = templateData.Item2.description,
                    thumbnail = templateData.Item2.preview,
                    sceneTemplate = templateData.Item2,
                    onCreateCallback = loadAdditively => CreateSceneFromTemplate(templateData.Item1, loadAdditively)
                });
            }).ToList();

            sceneTemplateAssetInfos.Sort();
            sceneTemplateList.AddRange(sceneTemplateAssetInfos);

            sceneTemplateList.Add(s_EmptySceneTemplateInfo);
            sceneTemplateList.Add(s_BasicSceneTemplateInfo);

            return(sceneTemplateList);
        }
Пример #2
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();
            }
        }
Пример #3
0
 public SceneTemplateCreationEvent(SceneTemplateAsset template, TemplateCreationType templateCreationType)
 {
     this.templateCreationType = Enum.GetName(typeof(TemplateCreationType), templateCreationType);
     sceneName = AssetDatabase.GetAssetPath(template.templateScene);
     hasCloneableDependencies   = FillAnalyticDepInfos(template, dependencyInfos);
     numberOfTemplatesInProject = SceneTemplateUtils.GetSceneTemplates().Count();
 }
        private void ValidatePosition()
        {
            const float tolerance = 0.0001f;

            if (Math.Abs(position.xMin) < tolerance && position.yMin < tolerance)
            {
                position = SceneTemplateUtils.GetMainWindowCenteredPosition(k_DefaultWindowSize);
            }
        }
        private void CreateAllSceneTemplateListsUI(VisualElement rootContainer)
        {
            if (m_SceneTemplateInfos == null)
            {
                return;
            }

            var templateItems = CreateGridViewItems();

            m_GridView = new GridView(templateItems, L10n.Tr("Scene Templates in Project"), k_ListViewRowHeight, k_MinTileSize, k_MaxTileSize, k_ShowThumbnailTileSizeThreshold, m_DefaultThumbnail, 4f / 3f);
            m_GridView.wrapAroundKeyboardNavigation = true;
            m_GridView.sizeLevel = EditorPrefs.GetFloat(GetKeyName(nameof(m_GridView.sizeLevel)), 128);
            rootContainer.Add(m_GridView);

            m_GridView.SetPinned(m_SceneTemplateInfos.Where(template => template.isPinned).Select(template => template.GetHashCode()));

            m_GridView.onSelectionChanged += OnTemplateListViewSelectionChanged;
            m_GridView.onPinnedChanged    += OnPinnedChanged;
            m_GridView.onItemsActivated   += objects =>
            {
                var sceneTemplateInfo = objects.First().userData as SceneTemplateInfo;
                if (sceneTemplateInfo == null)
                {
                    return;
                }
                if (m_SelectedButtonIndex != -1)
                {
                    m_Buttons[m_SelectedButtonIndex].callback(sceneTemplateInfo);
                }
            };

            var toSelect = templateItems.FirstOrDefault(item => item.userData.Equals(m_LastSelectedTemplate));

            if (toSelect != null)
            {
                m_GridView.SetSelection(toSelect);
            }
            else
            {
                m_GridView.SetSelection(templateItems.First());
            }

            m_NoUserTemplateHelpBox = new HelpBox(L10n.Tr("To begin using a template, create a template from an existing scene in your project. Click to see Scene template documentation."), HelpBoxMessageType.Info);
            m_NoUserTemplateHelpBox.AddToClassList(Styles.sceneTemplateNoTemplateHelpBox);
            m_NoUserTemplateHelpBox.RegisterCallback <MouseDownEvent>(e =>
            {
                SceneTemplateUtils.OpenDocumentationUrl();
            });
            m_NoUserTemplateHelpBox.style.display = m_SceneTemplateInfos.All(t => t.IsInMemoryScene) ? DisplayStyle.Flex : DisplayStyle.None;
            m_GridView.Insert(2, m_NoUserTemplateHelpBox);

            EditorApplication.delayCall += () =>
            {
                m_GridView.SetFocus();
            };
        }
        private void OnSceneTemplateAssetModified(SceneTemplateAsset asset)
        {
            m_SceneTemplateInfos = SceneTemplateUtils.GetSceneTemplateInfos();
            var lastSelectedTemplateIndex = m_SceneTemplateInfos.IndexOf(m_LastSelectedTemplate);

            if (lastSelectedTemplateIndex == -1)
            {
                SetLastSelectedTemplate(GetDefaultSceneTemplateInfo());
            }
            else
            {
                SetLastSelectedTemplate(m_SceneTemplateInfos[lastSelectedTemplateIndex]);
            }

            RefreshTemplateGridView();

            UpdateTemplateDescriptionUI(m_LastSelectedTemplate);
        }
Пример #7
0
        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);
        }
        private void SetupData()
        {
            m_SceneTemplateInfos = SceneTemplateUtils.GetSceneTemplateInfos();
            LoadSessionPreferences();
            m_DefaultThumbnail = EditorGUIUtility.IconContent("d_SceneAsset Icon").image as Texture2D;

            foreach (var builtinTemplateInfo in SceneTemplateUtils.builtinTemplateInfos)
            {
                if (builtinTemplateInfo.thumbnail == null)
                {
                    builtinTemplateInfo.thumbnail = EditorResources.Load <Texture2D>(builtinTemplateInfo.thumbnailPath);
                    Assert.IsNotNull(builtinTemplateInfo.thumbnail);
                }

                if (builtinTemplateInfo.badge == null && !string.IsNullOrEmpty(builtinTemplateInfo.badgePath))
                {
                    builtinTemplateInfo.badge = EditorResources.Load <Texture2D>(builtinTemplateInfo.badgePath);
                    Assert.IsNotNull(builtinTemplateInfo.badge);
                }
            }
        }
Пример #9
0
        static void UpdateSceneTemplatesOnSceneSave(Scene scene)
        {
            var infos = SceneTemplateUtils.GetSceneTemplateInfos();

            foreach (var sceneTemplateInfo in infos)
            {
                if (sceneTemplateInfo.IsInMemoryScene || sceneTemplateInfo.isReadonly || sceneTemplateInfo.sceneTemplate == null)
                {
                    continue;
                }

                var scenePath = sceneTemplateInfo.sceneTemplate.GetTemplateScenePath();
                if (string.IsNullOrEmpty(scenePath))
                {
                    continue;
                }
                if (!scene.path.Equals(scenePath, StringComparison.Ordinal))
                {
                    continue;
                }
                sceneTemplateInfo.sceneTemplate.UpdateDependencies();
            }
        }
Пример #10
0
        static void InstantiateDefaultScene(CommandExecuteContext context)
        {
            if (SceneTemplatePreferences.Get().newDefaultSceneOverride == SceneTemplatePreferences.NewDefaultSceneOverride.DefaultBuiltin)
            {
                EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
                return;
            }

            var templateInfos = SceneTemplateUtils.GetSceneTemplateInfos();
            var templateInfo  = templateInfos.FirstOrDefault(info => info.isPinned && !info.IsInMemoryScene);

            if (templateInfo == null)
            {
                templateInfo = templateInfos.FirstOrDefault(info => !info.isPinned && !info.IsInMemoryScene);
            }

            if (templateInfo != null && templateInfo.sceneTemplate)
            {
                Instantiate(templateInfo.sceneTemplate, false);
                return;
            }

            EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects, NewSceneMode.Single);
        }
        private static void Send(EventName eventName, object eventData)
        {
#if SCENE_TEMPLATE_ANALYTICS_LOGGING
#else
            if (SceneTemplateUtils.IsDeveloperMode())
            {
                return;
            }
#endif

            if (!RegisterEvents())
            {
#if SCENE_TEMPLATE_ANALYTICS_LOGGING
                Console.WriteLine($"[ST] Analytics disabled: event='{eventName}', time='{DateTime.Now:HH:mm:ss}', payload={EditorJsonUtility.ToJson(eventData, true)}");
#endif
                return;
            }
            try
            {
                var result = EditorAnalytics.SendEventWithLimit(eventName.ToString(), eventData);
                if (result == AnalyticsResult.Ok)
                {
#if SCENE_TEMPLATE_ANALYTICS_LOGGING
                    Console.WriteLine($"[ST] Event='{eventName}', time='{DateTime.Now:HH:mm:ss}', payload={EditorJsonUtility.ToJson(eventData, true)}");
#endif
                }
                else
                {
                    Console.WriteLine($"[ST] Failed to send event {eventName}. Result: {result}");
                }
            }
            catch (Exception)
            {
                // ignored
            }
        }
Пример #12
0
        private static void SaveTemplateFromCurrentScene()
        {
            var currentScene = SceneManager.GetActiveScene();

            if (string.IsNullOrEmpty(currentScene.path))
            {
                var suggestedScenePath = SceneTemplateUtils.SaveFilePanelUniqueName(L10n.Tr("Save scene"), "Assets", "newscene", "unity");
                if (string.IsNullOrEmpty(suggestedScenePath) || !EditorSceneManager.SaveScene(EditorSceneManager.GetActiveScene(), suggestedScenePath))
                {
                    return;
                }
            }

            var sceneTemplateFile = SceneTemplateUtils.SaveFilePanelUniqueName(L10n.Tr("Save scene"), Path.GetDirectoryName(currentScene.path), Path.GetFileNameWithoutExtension(currentScene.path), SceneTemplateAsset.extension);

            if (string.IsNullOrEmpty(sceneTemplateFile))
            {
                return;
            }

            var sourceSceneAsset = AssetDatabase.LoadAssetAtPath <SceneAsset>(currentScene.path);

            CreateTemplateFromScene(sourceSceneAsset, sceneTemplateFile, SceneTemplateAnalytics.TemplateCreationType.SaveCurrentSceneAsTemplateMenu);
        }
Пример #13
0
        private static bool InstantiateScene(SceneTemplateAsset sceneTemplate, string sourceScenePath, ref string newSceneOutputPath)
        {
            if (String.IsNullOrEmpty(newSceneOutputPath))
            {
                newSceneOutputPath = SceneTemplateUtils.SaveFilePanelUniqueName(
                    $"Save scene instantiated from template ({sceneTemplate.name})",
                    SceneTemplateUtils.GetLastFolder("unity"),
                    Path.GetFileNameWithoutExtension(sourceScenePath), "unity");
                if (string.IsNullOrEmpty(newSceneOutputPath))
                {
                    return(false);
                }
            }

            if (Path.IsPathRooted(newSceneOutputPath))
            {
                newSceneOutputPath = FileUtil.GetProjectRelativePath(newSceneOutputPath);
            }

            if (sourceScenePath == newSceneOutputPath)
            {
                Debug.LogError($"Cannot instantiate over template scene: {newSceneOutputPath}");
                return(false);
            }

            var destinationDir = Path.GetDirectoryName(newSceneOutputPath);

            if (destinationDir != null && !Directory.Exists(destinationDir))
            {
                Directory.CreateDirectory(destinationDir);
            }

            AssetDatabase.CopyAsset(sourceScenePath, newSceneOutputPath);

            return(true);
        }
Пример #14
0
        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);
            }
        }
Пример #15
0
        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));
        }
 static SceneTemplateAnalytics()
 {
     Version = SceneTemplateUtils.GetPackageVersion();
 }
Пример #17
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 (!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));
        }
Пример #18
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);
        }
Пример #19
0
        private void CreateTemplateDescriptionUI(VisualElement rootContainer)
        {
            rootContainer.style.flexDirection = FlexDirection.Column;

            // Thumbnail container
            m_PreviewArea = new SceneTemplatePreviewArea(k_SceneTemplateThumbnailName, m_LastSelectedTemplate?.thumbnail, "No preview thumbnail available");
            var thumbnailElement = m_PreviewArea.Element;

            rootContainer.Add(thumbnailElement);

            rootContainer.RegisterCallback <GeometryChangedEvent>(evt => UpdatePreviewAreaSize());

            // Text container
            var sceneTitleLabel = new Label();

            sceneTitleLabel.name = k_SceneTemplateTitleLabelName;
            sceneTitleLabel.AddToClassList(StyleSheetLoader.Styles.classWrappingText);
            rootContainer.Add(sceneTitleLabel);

            var assetPathSection = new VisualElement();

            assetPathSection.name = k_SceneTemplatePathSection;
            {
                var scenePathLabel = new Label();
                scenePathLabel.name = k_SceneTemplatePathName;
                scenePathLabel.AddToClassList(StyleSheetLoader.Styles.classWrappingText);
                assetPathSection.Add(scenePathLabel);

                var editLocateRow = new VisualElement();
                editLocateRow.style.flexDirection = FlexDirection.Row;
                {
                    var scenePathLocate = new Label();
                    scenePathLocate.text = "Locate";
                    scenePathLocate.AddToClassList(StyleSheetLoader.Styles.classTextLink);
                    scenePathLocate.RegisterCallback <MouseDownEvent>(e =>
                    {
                        if (string.IsNullOrEmpty(scenePathLabel.text))
                        {
                            return;
                        }

                        var asset = AssetDatabase.LoadAssetAtPath <SceneTemplateAsset>(scenePathLabel.text);
                        if (!asset)
                        {
                            return;
                        }

                        EditorApplication.delayCall += () =>
                        {
                            EditorWindow.FocusWindowIfItsOpen(SceneTemplateUtils.GetProjectBrowserWindowType());
                            EditorApplication.delayCall += () => EditorGUIUtility.PingObject(asset);
                        };
                    });
                    editLocateRow.Add(scenePathLocate);

                    editLocateRow.Add(new Label()
                    {
                        text = " | "
                    });

                    var scenePathEdit = new Label();
                    scenePathEdit.name = k_SceneTemplateEditTemplateButtonName;
                    scenePathEdit.text = "Edit";
                    scenePathEdit.AddToClassList(StyleSheetLoader.Styles.classTextLink);
                    scenePathEdit.RegisterCallback <MouseDownEvent>(e =>
                    {
                        OnEditTemplate(m_LastSelectedTemplate);
                    });
                    editLocateRow.Add(scenePathEdit);
                }
                assetPathSection.Add(editLocateRow);
            }
            rootContainer.Add(assetPathSection);

            var descriptionSection = new VisualElement();

            descriptionSection.name = k_SceneTemplateDescriptionSection;
            {
                var descriptionLabel = new Label();
                descriptionLabel.AddToClassList(StyleSheetLoader.Styles.classHeaderLabel);
                descriptionLabel.text = "Description";
                descriptionSection.Add(descriptionLabel);

                var sceneDescriptionLabel = new Label();
                sceneDescriptionLabel.AddToClassList(StyleSheetLoader.Styles.classWrappingText);
                sceneDescriptionLabel.name = k_SceneTemplateDescriptionName;
                descriptionSection.Add(sceneDescriptionLabel);
            }
            rootContainer.Add(descriptionSection);
        }