//--------------------------------------------------------------------------------------------------
            // IO

            //Save .shader file
            private static Shader SaveShader(TCP2_Config config, Shader existingShader, string sourceCode, bool overwritePrompt, bool modifiedPrompt)
            {
                if (string.IsNullOrEmpty(config.Filename))
                {
                    Debug.LogError("[TCP2 Shader Generator] Can't save Shader: filename is null or empty!");
                    return(null);
                }

                //Save file
                var outputPath = OutputPath;
                var filename   = config.Filename;

                //Get existing shader exact path
                if (existingShader != null)
                {
                    outputPath = GetExistingShaderPath(config, existingShader);

                    /*
                     * if(config.Filename.Contains("/"))
                     * {
                     *      filename = config.Filename.Substring(config.Filename.LastIndexOf('/')+1);
                     * }
                     */
                }

                var systemPath = Application.dataPath + outputPath;

                if (!Directory.Exists(systemPath))
                {
                    Directory.CreateDirectory(systemPath);
                }

                var fullPath  = systemPath + filename + ".shader";
                var overwrite = true;

                if (overwritePrompt && File.Exists(fullPath))
                {
                    overwrite = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "The following shader already exists:\n\n" + fullPath + "\n\nOverwrite?", "Yes", "No");
                }

                if (modifiedPrompt)
                {
                    overwrite = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "The following shader seems to have been modified externally or manually:\n\n" + fullPath + "\n\nOverwrite anyway?", "Yes", "No");
                }

                if (overwrite)
                {
                    var directory = Path.GetDirectoryName(fullPath);
                    if (!Directory.Exists(directory))
                    {
                        Directory.CreateDirectory(directory);
                    }

                    //Write file to disk
                    File.WriteAllText(fullPath, sourceCode, Encoding.UTF8);
                    AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

                    //Import (to compile shader)
                    var assetPath = fullPath.Replace(Application.dataPath, "Assets");

                    var shader = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Shader)) as Shader;
                    if (SelectGeneratedShader)
                    {
                        Selection.objects = new Object[] { shader };
                    }

                    //Set ShaderImporter userData
                    var shaderImporter = ShaderImporter.GetAtPath(assetPath) as ShaderImporter;
                    if (shaderImporter != null)
                    {
                        //Set default textures
                        string[] names = new string[]
                        {
                            "_NoTileNoiseTex",
                            "_Ramp"
                        };
                        Texture[] textures = new Texture[]
                        {
                            AssetDatabase.LoadAssetAtPath <Texture2D>(AssetDatabase.GUIDToAssetPath("af5515bfe14f1af4a9b8b3bf306b9261")),
                            AssetDatabase.LoadAssetAtPath <Texture2D>(AssetDatabase.GUIDToAssetPath("ccad9b0732473ee4e95de81e50e9050f"))
                        };
                        shaderImporter.SetDefaultTextures(names, textures);

                        //Get file hash to verify if it has been manually altered afterwards
                        var shaderHash = GetShaderContentHash(shaderImporter);

                        //Use hash if available, else use timestamp
                        var customDataList = new List <string>();
                        customDataList.Add(!string.IsNullOrEmpty(shaderHash) ? shaderHash : shaderImporter.assetTimeStamp.ToString());
                        customDataList.Add(config.GetShaderTargetCustomData());
                        var configTypeCustomData = config.GetConfigTypeCustomData();
                        if (configTypeCustomData != null)
                        {
                            customDataList.Add(configTypeCustomData);
                        }
                        customDataList.Add(config.GetConfigFileCustomData());

                        var userData = config.ToUserData(customDataList.ToArray());
                        shaderImporter.userData = userData;

                        //Needed to save userData in .meta file
                        AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.Default);
                    }
                    else
                    {
                        Debug.LogWarning("[TCP2 Shader Generator] Couldn't find ShaderImporter.\nMetadatas will be missing from the shader file.");
                    }

                    return(shader);
                }

                return(null);
            }
    static public TCP2_Config CreateFromShader(Shader shader)
    {
        ShaderImporter shaderImporter = ShaderImporter.GetAtPath(AssetDatabase.GetAssetPath(shader)) as ShaderImporter;

        string[] features;
        string[] flags;
        string[] customData;
        Dictionary <string, string> keywords;

        TCP2_ShaderGeneratorUtils.ParseUserData(shaderImporter, out features, out flags, out keywords, out customData);
        if (features != null && features.Length > 0 && features[0] == "USER")
        {
            var config = new TCP2_Config();
            config.ShaderName = shader.name;
            config.Filename   = System.IO.Path.GetFileName(AssetDatabase.GetAssetPath(shader));
            config.Features   = new List <string>(features);
            config.Flags      = (flags != null) ? new List <string>(flags) : new List <string>();
            config.Keywords   = (keywords != null) ? new Dictionary <string, string>(keywords) : new Dictionary <string, string>();
            config.AutoNames();

            //mCurrentShader = shader;
            //mConfigChoice = mUserShadersLabels.IndexOf(shader.name);
            //mDirtyConfig = false;
            //AutoNames();
            //mCurrentHash = mCurrentConfig.ToHash();

            config.isModifiedExternally = false;
            if (customData != null && customData.Length > 0)
            {
                foreach (string data in customData)
                {
                    //Hash
                    if (data.Length > 0 && data[0] == 'h')
                    {
                        string dataHash = data;
                        string fileHash = TCP2_ShaderGeneratorUtils.GetShaderContentHash(shaderImporter);

                        if (!string.IsNullOrEmpty(fileHash) && dataHash != fileHash)
                        {
                            config.isModifiedExternally = true;
                        }
                    }
                    //Timestamp
                    else
                    {
                        ulong timestamp;
                        if (ulong.TryParse(data, out timestamp))
                        {
                            if (shaderImporter.assetTimeStamp != timestamp)
                            {
                                config.isModifiedExternally = true;
                            }
                        }
                    }

                    //Shader Model target
                    if (data.StartsWith("SM:"))
                    {
                        config.shaderTarget = int.Parse(data.Substring(3));
                    }

                    //Configuration Type
                    if (data.StartsWith("CT:"))
                    {
                        config.configType = data.Substring(3);
                    }

                    //Configuration File
                    if (data.StartsWith("CF:"))
                    {
                        config.templateFile = data.Substring(3);
                    }
                }
            }

            return(config);
        }
        else
        {
            return(null);
        }
    }
Exemplo n.º 3
0
    //--------------------------------------------------------------------------------------------------
    // IO

    //Save .shader file
    static private Shader SaveShader(TCP2_Config config, string sourceCode, bool overwritePrompt, bool modifiedPrompt)
    {
        if (string.IsNullOrEmpty(config.Filename))
        {
            Debug.LogError("[TCP2 Shader Generator] Can't save Shader: filename is null or empty!");
            return(null);
        }

        //Save file
        string path = Application.dataPath + OUTPUT_PATH;

        if (!System.IO.Directory.Exists(path))
        {
            System.IO.Directory.CreateDirectory(path);
        }

        string fullPath  = path + config.Filename + ".shader";
        bool   overwrite = true;

        if (overwritePrompt && System.IO.File.Exists(fullPath))
        {
            overwrite = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "The following shader already exists:\n\n" + fullPath + "\n\nOverwrite?", "Yes", "No");
        }

        if (modifiedPrompt)
        {
            overwrite = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "The following shader seems to have been modified externally or manually:\n\n" + fullPath + "\n\nOverwrite anyway?", "Yes", "No");
        }

        if (overwrite)
        {
            string directory = System.IO.Path.GetDirectoryName(path + config.Filename);
            if (!System.IO.Directory.Exists(directory))
            {
                System.IO.Directory.CreateDirectory(directory);
            }

            //Write file to disk
            System.IO.File.WriteAllText(path + config.Filename + ".shader", sourceCode, System.Text.Encoding.UTF8);
            AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

            //Import (to compile shader)
            string assetPath = "Assets" + OUTPUT_PATH + config.Filename + ".shader";

            Shader shader = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Shader)) as Shader;
            if (SelectGeneratedShader)
            {
                Selection.objects = new Object[] { shader };
            }

            //Set ShaderImporter userData
            ShaderImporter shaderImporter = ShaderImporter.GetAtPath(assetPath) as ShaderImporter;
            if (shaderImporter != null)
            {
                string[] customData = new string[] { shaderImporter.assetTimeStamp.ToString() };
                string   userData   = config.ToUserData(customData);
                shaderImporter.userData = userData;

                //Needed to save userData in .meta file
                AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.Default);
            }
            else
            {
                Debug.LogWarning("[TCP2 Shader Generator] Couldn't find ShaderImporter.\nMetadatas will be missing from the shader file.");
            }

            return(shader);
        }

        return(null);
    }
Exemplo n.º 4
0
    void OnGUI()
    {
        sGUIEnabled = GUI.enabled;

        EditorGUILayout.BeginHorizontal();
        TCP2_GUI.HeaderBig("TOONY COLORS PRO 2 - SHADER GENERATOR");
        TCP2_GUI.HelpButton("Shader Generator");
        EditorGUILayout.EndHorizontal();
        TCP2_GUI.Separator();

        float lW = EditorGUIUtility.labelWidth;

        EditorGUIUtility.labelWidth = 105f;

        //Avoid refreshing Template meta at every Repaint
        EditorGUILayout.BeginHorizontal();
        TextAsset _tmpTemplate = EditorGUILayout.ObjectField("Template:", Template.textAsset, typeof(TextAsset), false) as TextAsset;

        if (_tmpTemplate != Template.textAsset)
        {
            Template.SetTextAsset(_tmpTemplate);
        }
        //Load template
        if (loadTemplateMenu != null)
        {
            if (GUILayout.Button("Load ▼", EditorStyles.miniButton, GUILayout.ExpandWidth(false)))
            {
                loadTemplateMenu.ShowAsContext();
            }
        }

        /*
         * if(GUILayout.Button("Reload", EditorStyles.miniButton, GUILayout.ExpandWidth(false)))
         * {
         *      Template.Reload();
         * }
         */
        EditorGUILayout.EndHorizontal();

        //Template not found
        if (Template == null || Template.textAsset == null)
        {
            EditorGUILayout.HelpBox("Couldn't find template file!\n\nVerify that the file 'TCP2_ShaderTemplate_Default.txt' is in your project.\nPlease reimport the pack if you can't find it!", MessageType.Error);
            return;
        }

        //Infobox for custom templates
        if (!string.IsNullOrEmpty(Template.templateInfo))
        {
            TCP2_GUI.HelpBoxLayout(Template.templateInfo, MessageType.Info);
        }
        if (!string.IsNullOrEmpty(Template.templateWarning))
        {
            TCP2_GUI.HelpBoxLayout(Template.templateWarning, MessageType.Warning);
        }

        TCP2_GUI.Separator();

        //If current shader is unsaved, show yellow color
        Color gColor = GUI.color;

        GUI.color = mDirtyConfig ? gColor * unsavedChangesColor : GUI.color;

        EditorGUI.BeginChangeCheck();
        mCurrentShader = EditorGUILayout.ObjectField("Current Shader:", mCurrentShader, typeof(Shader), false) as Shader;
        if (EditorGUI.EndChangeCheck())
        {
            if (mCurrentShader != null)
            {
                LoadCurrentConfigFromShader(mCurrentShader);
            }
        }
        EditorGUILayout.BeginHorizontal();

        GUILayout.Space(EditorGUIUtility.labelWidth + 4);
        if (mDirtyConfig)
        {
            var guiContent = new GUIContent("Unsaved changes");
            var rect       = GUILayoutUtility.GetRect(guiContent, EditorStyles.helpBox, GUILayout.Height(16));
            rect.y -= 2;
            GUI.Label(rect, guiContent, EditorStyles.helpBox);
        }

        GUILayout.FlexibleSpace();
        using (new EditorGUI.DisabledScope(mCurrentShader == null))
        {
            if (GUILayout.Button("Copy", EditorStyles.miniButtonLeft, GUILayout.Width(60f), GUILayout.Height(16)))
            {
                CopyShader();
            }
        }
        if (GUILayout.Button("Load ▼", EditorStyles.miniButtonMid, GUILayout.Width(60f), GUILayout.Height(16)))
        {
            loadShadersMenu.ShowAsContext();
        }
        if (GUILayout.Button("New", EditorStyles.miniButtonRight, GUILayout.Width(60f), GUILayout.Height(16)))
        {
            NewShader();
        }
        GUILayout.Space(18);            //leave space to align with the Object Field box
        EditorGUILayout.EndHorizontal();
        GUI.color = gColor;

        if (mCurrentConfig == null)
        {
            NewShader();
        }

        if (mCurrentConfig.isModifiedExternally)
        {
            EditorGUILayout.HelpBox("It looks like this shader has been modified externally/manually. Updating it will overwrite the changes.", MessageType.Warning);
        }

        /*
         * if(mUserShaders != null && mUserShaders.Length > 0)
         * {
         *      EditorGUI.BeginChangeCheck();
         *      int prevChoice = mConfigChoice;
         *      Color gColor = GUI.color;
         *      GUI.color = mDirtyConfig ? gColor * Color.yellow : GUI.color;
         *      GUILayout.BeginHorizontal();
         *      mConfigChoice = EditorGUILayout.Popup("Load Shader:", mConfigChoice, mUserShadersLabels.ToArray());
         *      if(GUILayout.Button("◄", EditorStyles.miniButtonLeft, GUILayout.Width(22)))
         *      {
         *              mConfigChoice--;
         *              if(mConfigChoice < 1) mConfigChoice = mUserShaders.Length;
         *      }
         *      if(GUILayout.Button("►", EditorStyles.miniButtonRight,GUILayout.Width(22)))
         *      {
         *              mConfigChoice++;
         *              if(mConfigChoice > mUserShaders.Length) mConfigChoice = 1;
         *      }
         *      GUILayout.EndHorizontal();
         *      GUI.color = gColor;
         *      if(EditorGUI.EndChangeCheck() && prevChoice != mConfigChoice)
         *      {
         *              bool load = true;
         *              if(mDirtyConfig)
         *              {
         *                      if(mCurrentShader != null)
         *                              load = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "You have unsaved changes for the following shader:\n\n" + mCurrentShader.name + "\n\nDiscard the changes and load a new shader?", "Yes", "No");
         *                      else
         *                              load = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "You have unsaved changes.\n\nDiscard the changes and load a new shader?", "Yes", "No");
         *              }
         *
         *              if(load)
         *              {
         *                      //New Shader
         *                      if(mConfigChoice == 0)
         *                      {
         *                              NewShader();
         *                      }
         *                      else
         *                      {
         *                              //Load selected Shader
         *                              Shader selectedShader = mUserShaders[mConfigChoice-1];
         *                              mCurrentShader = selectedShader;
         *                              LoadCurrentConfigFromShader(mCurrentShader);
         *                      }
         *              }
         *              else
         *              {
         *                      //Revert choice
         *                      mConfigChoice = prevChoice;
         *              }
         *      }
         * }
         */

        EditorGUIUtility.labelWidth = lW;

        //Name & Filename
        TCP2_GUI.Separator();
        GUI.enabled = (mCurrentShader == null);
        EditorGUI.BeginChangeCheck();
        mCurrentConfig.ShaderName = EditorGUILayout.TextField(new GUIContent("Shader Name", "Path will indicate how to find the Shader in Unity's drop-down list"), mCurrentConfig.ShaderName);
        mCurrentConfig.ShaderName = Regex.Replace(mCurrentConfig.ShaderName, @"[^a-zA-Z0-9 _!/]", "");
        if (EditorGUI.EndChangeCheck() && sAutoNames)
        {
            mCurrentConfig.AutoNames();
        }
        GUI.enabled &= !sAutoNames;
        EditorGUILayout.BeginHorizontal();
        mCurrentConfig.Filename = EditorGUILayout.TextField("File Name", mCurrentConfig.Filename);
        mCurrentConfig.Filename = Regex.Replace(mCurrentConfig.Filename, @"[^a-zA-Z0-9 _!/]", "");
        GUILayout.Label(".shader", GUILayout.Width(50f));
        EditorGUILayout.EndHorizontal();
        GUI.enabled = sGUIEnabled;

        Space();

        //########################################################################################################
        // FEATURES

        TCP2_GUI.Header("FEATURES");

        //Scroll view
        mScrollPosition = EditorGUILayout.BeginScrollView(mScrollPosition);
        EditorGUI.BeginChangeCheck();

        if (Template.newSystem)
        {
            //New UI embedded into Template
            Template.FeaturesGUI(mCurrentConfig);

            if (mFirstHashPass)
            {
                mCurrentHash   = mCurrentConfig.ToHash();
                mFirstHashPass = false;
            }
        }
        else
        {
            EditorGUILayout.HelpBox("Old template versions aren't supported anymore.", MessageType.Warning);
        }

#if DEBUG_MODE
        TCP2_GUI.SeparatorBig();

        TCP2_GUI.SubHeaderGray("DEBUG MODE");

        GUILayout.BeginHorizontal();
        mDebugText = EditorGUILayout.TextField("Custom", mDebugText);
        if (GUILayout.Button("Add Feature", EditorStyles.miniButtonLeft, GUILayout.Width(80f)))
        {
            mCurrentConfig.Features.Add(mDebugText);
        }
        if (GUILayout.Button("Add Flag", EditorStyles.miniButtonRight, GUILayout.Width(80f)))
        {
            mCurrentConfig.Flags.Add(mDebugText);
        }

        GUILayout.EndHorizontal();
        GUILayout.Label("Features:");
        GUILayout.BeginHorizontal();
        int count = 0;
        for (int i = 0; i < mCurrentConfig.Features.Count; i++)
        {
            if (count >= 3)
            {
                count = 0;
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
            }
            count++;
            if (GUILayout.Button(mCurrentConfig.Features[i], EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
            {
                mCurrentConfig.Features.RemoveAt(i);
                break;
            }
        }
        GUILayout.EndHorizontal();
        GUILayout.Label("Flags:");
        GUILayout.BeginHorizontal();
        count = 0;
        for (int i = 0; i < mCurrentConfig.Flags.Count; i++)
        {
            if (count >= 3)
            {
                count = 0;
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
            }
            count++;
            if (GUILayout.Button(mCurrentConfig.Flags[i], EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
            {
                mCurrentConfig.Flags.RemoveAt(i);
                break;
            }
        }
        GUILayout.EndHorizontal();
        GUILayout.Label("Keywords:");
        GUILayout.BeginHorizontal();
        count = 0;
        foreach (KeyValuePair <string, string> kvp in mCurrentConfig.Keywords)
        {
            if (count >= 3)
            {
                count = 0;
                GUILayout.EndHorizontal();
                GUILayout.BeginHorizontal();
            }
            count++;
            if (GUILayout.Button(kvp.Key + ":" + kvp.Value, EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
            {
                mCurrentConfig.Keywords.Remove(kvp.Key);
                break;
            }
        }
        GUILayout.EndHorizontal();

        //----------------------------------------------------------------

        Space();
        if (mCurrentShader != null)
        {
            if (mCurrentShaderImporter == null)
            {
                mCurrentShaderImporter = ShaderImporter.GetAtPath(AssetDatabase.GetAssetPath(mCurrentShader)) as ShaderImporter;
            }

            if (mCurrentShaderImporter != null && mCurrentShaderImporter.GetShader() == mCurrentShader)
            {
                mDebugExpandUserData = EditorGUILayout.Foldout(mDebugExpandUserData, "Shader UserData");
                if (mDebugExpandUserData)
                {
                    string[] userData = mCurrentShaderImporter.userData.Split(',');
                    foreach (var str in userData)
                    {
                        GUILayout.Label(str);
                    }
                }
            }
        }
#endif

        //Update config
        if (EditorGUI.EndChangeCheck())
        {
            int newHash = mCurrentConfig.ToHash();
            if (newHash != mCurrentHash)
            {
                mDirtyConfig = true;
            }
            else
            {
                mDirtyConfig = false;
            }
        }

        //Scroll view
        EditorGUILayout.EndScrollView();

        Space();

        //GENERATE

        EditorGUILayout.BeginHorizontal();
        GUILayout.FlexibleSpace();
        GUI.color = mDirtyConfig ? gColor * unsavedChangesColor : GUI.color;
        if (GUILayout.Button(mCurrentShader == null ? "Generate Shader" : "Update Shader", GUILayout.Width(120f), GUILayout.Height(30f)))
        {
            if (Template == null)
            {
                EditorUtility.DisplayDialog("TCP2 : Shader Generation", "Can't generate shader: no Template file defined!\n\nYou most likely want to link the TCP2_User.txt file to the Template field in the Shader Generator.", "Ok");
                return;
            }

            //Set config type
            if (Template.templateType != null)
            {
                mCurrentConfig.configType = Template.templateType;
            }

            //Set config file
            mCurrentConfig.templateFile = Template.textAsset.name;

            Shader generatedShader = TCP2_ShaderGeneratorUtils.Compile(mCurrentConfig, mCurrentShader, Template, true, !sOverwriteConfigs);
            ReloadUserShaders();
            if (generatedShader != null)
            {
                mDirtyConfig = false;
                LoadCurrentConfigFromShader(generatedShader);
            }

            //Workaround to force the inspector to refresh, so that state is reset.
            //Needed in case of switching between specular/metallic and related
            //options, while the inspector is opened, so that it shows/hides the
            //relevant properties according to the changes.
            TCP2_MaterialInspector_SurfacePBS_SG.InspectorNeedsUpdate = true;
        }
        GUI.color = gColor;
        EditorGUILayout.EndHorizontal();
        TCP2_GUI.Separator();

        // OPTIONS
        TCP2_GUI.Header("OPTIONS");

        GUILayout.BeginHorizontal();
        sSelectGeneratedShader = GUILayout.Toggle(sSelectGeneratedShader, new GUIContent("Select Generated Shader", "Will select the generated file in the Project view"), GUILayout.Width(180f));
        sAutoNames             = GUILayout.Toggle(sAutoNames, new GUIContent("Automatic Name", "Will automatically generate the shader filename based on its UI name"), GUILayout.ExpandWidth(false));
        GUILayout.EndHorizontal();
        GUILayout.BeginHorizontal();
        sOverwriteConfigs = GUILayout.Toggle(sOverwriteConfigs, new GUIContent("Always overwrite shaders", "Overwrite shaders when generating/updating (no prompt)"), GUILayout.Width(180f));
        sHideDisabled     = GUILayout.Toggle(sHideDisabled, new GUIContent("Hide disabled fields", "Hide properties settings when they cannot be accessed"), GUILayout.ExpandWidth(false));
        GUILayout.EndHorizontal();

        EditorGUILayout.BeginHorizontal();
        EditorGUI.BeginChangeCheck();
        TCP2_ShaderGeneratorUtils.CustomOutputDir = GUILayout.Toggle(TCP2_ShaderGeneratorUtils.CustomOutputDir, new GUIContent("Custom Output Directory:", "Will save the generated shaders in a custom directory within the Project"), GUILayout.Width(165f));
        GUI.enabled &= TCP2_ShaderGeneratorUtils.CustomOutputDir;
        if (TCP2_ShaderGeneratorUtils.CustomOutputDir)
        {
            TCP2_ShaderGeneratorUtils.OutputPath = EditorGUILayout.TextField("", TCP2_ShaderGeneratorUtils.OutputPath);
            if (GUILayout.Button("Select...", EditorStyles.miniButton, GUILayout.ExpandWidth(false)))
            {
                string outputPath = TCP2_Utils.OpenFolderPanel_ProjectPath("Choose custom output directory for TCP2 generated shaders");
                if (!string.IsNullOrEmpty(outputPath))
                {
                    TCP2_ShaderGeneratorUtils.OutputPath = outputPath;
                }
            }
        }
        else
        {
            EditorGUILayout.TextField("", TCP2_ShaderGeneratorUtils.OUTPUT_PATH);
        }
        if (EditorGUI.EndChangeCheck())
        {
            ReloadUserShaders();
        }

        GUI.enabled = sGUIEnabled;
        EditorGUILayout.EndHorizontal();

        EditorGUI.BeginChangeCheck();
        sLoadAllShaders = GUILayout.Toggle(sLoadAllShaders, new GUIContent("Reload Shaders from all Project", "Load shaders from all your Project folders instead of just Toony Colors Pro 2.\nEnable it if you move your generated shader files outside of the default TCP2 Generated folder."), GUILayout.ExpandWidth(false));
        if (EditorGUI.EndChangeCheck())
        {
            ReloadUserShaders();
        }

        TCP2_ShaderGeneratorUtils.SelectGeneratedShader = sSelectGeneratedShader;
    }
Exemplo n.º 5
0
    //--------------------------------------------------------------------------------------------------
    // IO

    //Save .shader file
    static private Shader SaveShader(TCP2_Config config, Shader existingShader, string sourceCode, bool overwritePrompt, bool modifiedPrompt)
    {
        if (string.IsNullOrEmpty(config.Filename))
        {
            Debug.LogError("[TCP2 Shader Generator] Can't save Shader: filename is null or empty!");
            return(null);
        }

        //Save file
        string outputPath = OutputPath;

        if (existingShader != null)
        {
            outputPath = GetExistingShaderPath(config, existingShader);
        }

        string systemPath = Application.dataPath + outputPath;

        if (!Directory.Exists(systemPath))
        {
            Directory.CreateDirectory(systemPath);
        }

        string fullPath  = systemPath + config.Filename + ".shader";
        bool   overwrite = true;

        if (overwritePrompt && File.Exists(fullPath))
        {
            overwrite = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "The following shader already exists:\n\n" + fullPath + "\n\nOverwrite?", "Yes", "No");
        }

        if (modifiedPrompt)
        {
            overwrite = EditorUtility.DisplayDialog("TCP2 : Shader Generation", "The following shader seems to have been modified externally or manually:\n\n" + fullPath + "\n\nOverwrite anyway?", "Yes", "No");
        }

        if (overwrite)
        {
            string directory = Path.GetDirectoryName(systemPath + config.Filename);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            //Write file to disk
            File.WriteAllText(systemPath + config.Filename + ".shader", sourceCode, System.Text.Encoding.UTF8);
            AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);

            //Import (to compile shader)
            string assetPath = "Assets" + outputPath + config.Filename + ".shader";

            Shader shader = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Shader)) as Shader;
            if (SelectGeneratedShader)
            {
                Selection.objects = new Object[] { shader };
            }

            //Set ShaderImporter userData
            ShaderImporter shaderImporter = ShaderImporter.GetAtPath(assetPath) as ShaderImporter;
            if (shaderImporter != null)
            {
                //Get file hash to verify if it has been manually altered afterwards
                string shaderHash = GetShaderContentHash(shaderImporter);

                //Use hash if available, else use timestamp
                List <string> customDataList = new List <string>();
                customDataList.Add(!string.IsNullOrEmpty(shaderHash) ? shaderHash : shaderImporter.assetTimeStamp.ToString());
                customDataList.Add(config.GetShaderTargetCustomData());
                string configTypeCustomData = config.GetConfigTypeCustomData();
                if (configTypeCustomData != null)
                {
                    customDataList.Add(configTypeCustomData);
                }
                customDataList.Add(config.GetConfigFileCustomData());

                string userData = config.ToUserData(customDataList.ToArray());
                shaderImporter.userData = userData;

                //Needed to save userData in .meta file
                AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.Default);
            }
            else
            {
                Debug.LogWarning("[TCP2 Shader Generator] Couldn't find ShaderImporter.\nMetadatas will be missing from the shader file.");
            }

            return(shader);
        }

        return(null);
    }
Exemplo n.º 6
0
    private void LoadCurrentConfigFromShader(Shader shader)
    {
        ShaderImporter shaderImporter = ShaderImporter.GetAtPath(AssetDatabase.GetAssetPath(shader)) as ShaderImporter;

        string[] features;
        string[] flags;
        string[] customData;
        Dictionary <string, string> keywords;

        TCP2_ShaderGeneratorUtils.ParseUserData(shaderImporter, out features, out flags, out keywords, out customData);
        if (features != null && features.Length > 0 && features[0] == "USER")
        {
            mCurrentConfig            = new TCP2_Config();
            mCurrentConfig.ShaderName = shader.name;
            mCurrentConfig.Filename   = System.IO.Path.GetFileName(AssetDatabase.GetAssetPath(shader));
            mCurrentConfig.Features   = new List <string>(features);
            mCurrentConfig.Flags      = (flags != null) ? new List <string>(flags) : new List <string>();
            mCurrentConfig.Keywords   = (keywords != null) ? new Dictionary <string, string>(keywords) : new Dictionary <string, string>();
            mCurrentShader            = shader;
            mConfigChoice             = mUserShadersLabels.IndexOf(shader.name);
            mDirtyConfig = false;
            AutoNames();
            mCurrentHash = mCurrentConfig.ToHash();

            mIsModified = false;
            if (customData != null && customData.Length > 0)
            {
                foreach (string data in customData)
                {
                    //Hash
                    if (data.Length > 0 && data[0] == 'h')
                    {
                        string dataHash = data;
                        string fileHash = TCP2_ShaderGeneratorUtils.GetShaderContentHash(shaderImporter);

                        if (!string.IsNullOrEmpty(fileHash) && dataHash != fileHash)
                        {
                            mIsModified = true;
                        }
                    }
                    //Timestamp
                    else
                    {
                        ulong timestamp;
                        if (ulong.TryParse(data, out timestamp))
                        {
                            if (shaderImporter.assetTimeStamp != timestamp)
                            {
                                mIsModified = true;
                            }
                        }
                    }
                }
            }
        }
        else
        {
            EditorApplication.Beep();
            this.ShowNotification(new GUIContent("Invalid shader loaded: it doesn't seem to have been generated by the TCP2 Shader Generator!"));
            mCurrentShader = null;
            NewShader();
        }
    }
Exemplo n.º 7
0
    // Create a material instance of a given shader and configure textures and such
    void CreateMaterial(Shader shader)
    {
        string shaderPath       = AssetDatabase.GetAssetPath(shader);
        string shaderDirectory  = Path.GetDirectoryName(shaderPath);
        string shaderParentPath = Path.GetDirectoryName(Path.GetDirectoryName(shaderPath));
        string shaderName       = shader.name.Substring("Shade/".Length);
        string materialPath     = Path.Combine(shaderParentPath, shaderName);

        Material material = AssetDatabase.LoadAssetAtPath <Material>(materialPath + ".mat");

        if (material == null)
        {
            material = new Material(shader);
            AssetDatabase.CreateAsset(material, materialPath + ".mat");
        }

        material.shader = shader;

        // Find the Graph.json file for this shader, find any Texture nodes and properly configure the associated material properties for them
        TextAsset      shaderGraphAsset = AssetDatabase.LoadAssetAtPath <TextAsset>(Path.Combine(shaderDirectory, "Graph.json"));
        ShaderGraph    graph            = JsonUtility.FromJson <ShaderGraph>(shaderGraphAsset.text);
        ShaderImporter shaderImporter   = ShaderImporter.GetAtPath(shaderPath) as ShaderImporter;

        string[] textureTypes =
        {
            "Texture",
            "Gradient",
            "Bake",
            "Tiler"
        };

        foreach (ShaderNode n in graph.nodes)
        {
            if (n.options.userLabel != null)
            {
                string lowercaseName = Char.ToLowerInvariant(n.options.userLabel[0]) + n.options.userLabel.Substring(1);
                string propertyName  = "_" + lowercaseName.Replace(" ", "");

                if (Array.Exists(textureTypes, element => element == n.name))
                {
                    string    textureName = n.options.value != null ? n.options.value : n.options.userLabel;
                    Texture2D tex         = AssetDatabase.LoadAssetAtPath <Texture2D>(Path.Combine(shaderDirectory, textureName + ".png"));
                    if (tex != null)
                    {
                        material.SetTexture(propertyName, tex);
                        shaderImporter.SetDefaultTextures(new[] { propertyName }, new[] { tex });

                        string          texturePath = AssetDatabase.GetAssetPath(tex);
                        TextureImporter importer    = (TextureImporter)AssetImporter.GetAtPath(texturePath);

                        if (n.options.wrapMode != null)
                        {
                            switch (n.options.wrapMode)
                            {
                            case "repeat":
                                importer.wrapMode = TextureWrapMode.Repeat;
                                break;

                            case "clamp":
                                importer.wrapMode = TextureWrapMode.Clamp;
                                break;

                            case "mirror":
                                importer.wrapMode = TextureWrapMode.Mirror;
                                break;
                            }
                        }
                        else
                        {
                            importer.wrapMode = TextureWrapMode.Clamp;
                        }

                        if (n.options.filterMode != null)
                        {
                            switch (n.options.filterMode)
                            {
                            case "point":
                                importer.filterMode = FilterMode.Point;
                                break;

                            case "linear":
                                importer.filterMode = n.options.generateMipmaps ? FilterMode.Trilinear : FilterMode.Bilinear;
                                break;
                            }
                        }

                        importer.textureType = n.options.isNormalMap ? TextureImporterType.NormalMap : TextureImporterType.Default;

                        importer.SaveAndReimport();
                    }
                }
            }
        }
    }