using System; using System.IO; using UnityEditor.Experimental.GraphView; using UnityEngine; using UnityEngine.Rendering; namespace UnityEditor.ShaderGraph { static class CreateShaderGraph { [MenuItem("Assets/Create/Shader Graph/Blank Shader Graph", priority = CoreUtils.Sections.section1 + CoreUtils.Priorities.assetsCreateShaderMenuPriority)] public static void CreateBlankShaderGraph() { CreateFromTemplate(null, string.Empty, useProjectBrowserIfAvailable:true); } [MenuItem("Assets/Create/Shader Graph/From Template...")] public static void CreateFromTemplate() { CreateFromTemplate(null, useProjectBrowserIfAvailable:true); } /// /// Prompts the user to create a new Shader Graph from a Template. /// /// The Template Browser opens if is null. /// /// Callback to execute with the created shader graph asset. /// Shader Graph template file. Use string.Empty for Blank Shader Graph. /// Defines a search query that will pre-filter the list of available templates /// Defines a search query that will filter the list of available templates (and will be editable by the user) /// When false, the save file dialog is used, otherwise the project window is used (if visible) /// New Shader Graph filename. internal static void CreateFromTemplate(Action callback, string templateSourcePath = null, string filename = null, string hiddenQuery = null, string initialQuery = null, bool useProjectBrowserIfAvailable = false) { if (!string.IsNullOrEmpty(templateSourcePath)) { if (!AssetDatabase.AssetPathExists(templateSourcePath)) { Debug.LogError($"Shader Graph Template File missing at path: {templateSourcePath}."); return; } if (Path.GetExtension(templateSourcePath) != $".{ShaderGraphImporter.Extension}") { Debug.LogError($"Shader Graph Template File {templateSourcePath} is not a Shader Graph asset."); return; } } bool projectWindowIsVisible = useProjectBrowserIfAvailable && EditorWindow.HasOpenInstances(); NewGraphFromTemplateAction action = ScriptableObject.CreateInstance(); if (callback != null) action.Callback = callback; if (!string.IsNullOrEmpty(filename)) action.Filename = filename; ShaderGraphTemplateHelper shaderGraphTemplateHelper = new ShaderGraphTemplateHelper(); if (templateSourcePath == null) { GraphViewTemplateWindow.ShowCreateFromTemplate(shaderGraphTemplateHelper, action.CreateAndRenameGraphFromTemplate, showSaveDialog: !projectWindowIsVisible, hiddenSearchQuery: hiddenQuery, initialSearchQuery: initialQuery); } else { if (shaderGraphTemplateHelper.TryGetTemplate(templateSourcePath, out GraphViewTemplateDescriptor graphViewTemplate)) shaderGraphTemplateHelper.RaiseTemplateUsed(graphViewTemplate); if (projectWindowIsVisible) { action.CreateAndRenameGraphFromTemplate(templateSourcePath, null); } else { string graphDestinationPath = shaderGraphTemplateHelper.saveFileDialogHelper.OpenSaveFileDialog(); if (!string.IsNullOrEmpty(graphDestinationPath)) action.CreateAndRenameGraphFromTemplate(templateSourcePath, graphDestinationPath); } } } /// /// Prompts the user to create a new Shader Graph from a Template and associated Material. /// The Template Browser opens if is null. /// /// Callback to execute with the created material. /// Shader Graph template file. Use string.Empty for Blank Shader Graph. /// /// New Shader Graph filename. internal static void CreateGraphAndMaterialFromTemplate(Action callback = null, string templateSourcePath = null, string filename = null, string hiddenSearchQuery = null, string initialSearchQuery = null) { CreateFromTemplate(template => { if (!string.IsNullOrEmpty(template)) { Material material; if (ShaderGraphPreferences.GetOrPromptGraphTemplateWorkflow() == ShaderGraphPreferences.GraphTemplateWorkflow.MaterialVariant) { var srcMaterial = AssetDatabase.LoadAssetAtPath(template); material = new Material(srcMaterial); material.parent = srcMaterial; } else { var shader = AssetDatabase.LoadAssetAtPath(template); material = new Material(shader); } var materialPath = Path.Combine(Path.GetDirectoryName(template), Path.GetFileNameWithoutExtension(template) + ".mat"); AssetDatabase.CreateAsset(material, materialPath); AssetDatabase.SaveAssetIfDirty(material); AssetDatabase.Refresh(ImportAssetOptions.Default); callback?.Invoke(material); } }, templateSourcePath, filename, hiddenSearchQuery, initialSearchQuery); } } }