//-------------------------------------------------------------------------------------------------- public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { mMaterialEditor = materialEditor; #if SHOW_DEFAULT_INSPECTOR base.OnGUI(); return; #else //Header EditorGUILayout.BeginHorizontal(); string label = (Screen.width > 450f) ? "TOONY COLORS PRO 2 - INSPECTOR (Generated Shader)" : (Screen.width > 300f ? "TOONY COLORS PRO 2 - INSPECTOR" : "TOONY COLORS PRO 2"); TCP2_GUI.HeaderBig(label); if (TCP2_GUI.Button(TCP2_GUI.CogIcon, "O", "Open in Shader Generator")) { if (targetMaterial.shader != null) { TCP2_ShaderGenerator.OpenWithShader(targetMaterial.shader); } } EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); //Iterate Shader properties materialEditor.serializedObject.Update(); SerializedProperty mShader = materialEditor.serializedObject.FindProperty("m_Shader"); if (materialEditor.isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null) { //Retina display fix EditorGUIUtility.labelWidth = TCP2_Utils.ScreenWidthRetina - 120f; EditorGUIUtility.fieldWidth = 64f; EditorGUI.BeginChangeCheck(); EditorGUI.indentLevel++; foreach (MaterialProperty p in properties) { if ((p.flags & (MaterialProperty.PropFlags.PerRendererData | MaterialProperty.PropFlags.HideInInspector)) == MaterialProperty.PropFlags.None) { mMaterialEditor.ShaderProperty(p, p.displayName); } } EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck()) { materialEditor.PropertiesChanged(); } } #endif // !SHOW_DEFAULT_INSPECTOR #if UNITY_5_5_OR_NEWER TCP2_GUI.Separator(); materialEditor.RenderQueueField(); #endif }
void OnGUI() { EditorGUILayout.BeginHorizontal(); TCP2_GUI.HeaderBig("TCP 2 - RAMP GENERATOR"); TCP2_GUI.HelpButton("Ramp Generator"); EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); SerializedObject so = new SerializedObject(this); SerializedProperty sp = so.FindProperty("mGradient"); EditorGUILayout.PropertyField(sp, GUIContent.none); textureWidth = EditorGUILayout.IntField("TEXTURE SIZE:", textureWidth); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("64", EditorStyles.miniButtonLeft)) { textureWidth = 64; } if (GUILayout.Button("128", EditorStyles.miniButtonMid)) { textureWidth = 128; } if (GUILayout.Button("256", EditorStyles.miniButtonMid)) { textureWidth = 256; } if (GUILayout.Button("512", EditorStyles.miniButtonMid)) { textureWidth = 512; } if (GUILayout.Button("1024", EditorStyles.miniButtonRight)) { textureWidth = 1024; } EditorGUILayout.EndHorizontal(); if (GUI.changed) { so.ApplyModifiedProperties(); mGradient.alphaKeys = new GradientAlphaKey[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }; } GUILayout.Space(8f); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("GENERATE", GUILayout.Width(120f), GUILayout.Height(34f))) { string path = EditorUtility.SaveFilePanelInProject("Save Generated Ramp", "TCP2_CustomRamp", "png", "Save Generated Ramp"); GenerateTexture(path); } EditorGUILayout.EndHorizontal(); }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props) { FindProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly m_MaterialEditor = materialEditor; var material = materialEditor.target as Material; // Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing // material to a standard shader. // Do this before any GUI code has been issued to prevent layout issues in subsequent GUILayout statements (case 780071) if (m_FirstTimeApply) { MaterialChanged(material, m_WorkflowMode); m_FirstTimeApply = false; } //TCP2 Header EditorGUILayout.BeginHorizontal(); var label = (Screen.width > 450f) ? "TOONY COLORS PRO 2 - INSPECTOR (Generated Shader)" : (Screen.width > 300f ? "TOONY COLORS PRO 2 - INSPECTOR" : "TOONY COLORS PRO 2"); TCP2_GUI.HeaderBig(label); if (TCP2_GUI.Button(TCP2_GUI.CogIcon, "O", "Open in Shader Generator")) { if (material.shader != null) { TCP2_ShaderGenerator.OpenWithShader(material.shader); } } EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); ShaderPropertiesGUI(material); #if UNITY_5_5_OR_NEWER materialEditor.RenderQueueField(); #endif #if UNITY_5_6_OR_NEWER materialEditor.EnableInstancingField(); #endif }
void OnGUI() { EditorGUILayout.BeginHorizontal(); TCP2_GUI.HeaderBig(editMode ? "TCP 2 - RAMP EDITOR" : "TCP 2 - RAMP GENERATOR"); TCP2_GUI.HelpButton("Ramp Generator"); EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); serializedObject.Update(); if (editMode) { if (!isNewTexture) { var msg = "This will affect <b>all materials</b> that use this texture!" + (editModeFromMaterial ? "\n\nSave as a new texture first if you want to affect this material only." : "\n\nSave as a new texture if you want to keep the original ramp."); EditorGUILayout.LabelField(GUIContent.none, new GUIContent(msg, TCP2_GUI.GetHelpBoxIcon(MessageType.Warning)), TCP2_GUI.HelpBoxRichTextStyle); } var rect = EditorGUILayout.GetControlRect(GUILayout.Height(16f)); var lw = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 50f; var enabled = GUI.enabled; GUI.enabled = false; EditorGUI.ObjectField(rect, "Editing: ", linkedTexture, typeof(Texture2D), false); EditorGUIUtility.labelWidth = lw; GUI.enabled = enabled; } else { /* * EditorGUILayout.BeginHorizontal(); * if (GUILayout.Toggle(tabIndex == 0, "1D RAMP", TCP2_GUI.Tab)) * tabIndex = 0; * if (GUILayout.Toggle(tabIndex == 1, "2D RAMP", TCP2_GUI.Tab)) * tabIndex = 1; * GUILayout.FlexibleSpace(); * EditorGUILayout.EndHorizontal(); * TCP2_GUI.SeparatorSimple(); */ } if (isRamp1d) { GUILayout.Label("Click on the gradient to edit it:"); EditorGUILayout.PropertyField(gradientProperty, GUIContent.none); } else { scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); gradients2dList.DoLayoutList(); EditorGUILayout.EndScrollView(); } if (!editMode) { if (isRamp1d) { textureWidth = EditorGUILayout.IntField("TEXTURE SIZE:", textureWidth); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("64", EditorStyles.miniButtonLeft)) { textureWidth = 64; } if (GUILayout.Button("128", EditorStyles.miniButtonMid)) { textureWidth = 128; } if (GUILayout.Button("256", EditorStyles.miniButtonMid)) { textureWidth = 256; } if (GUILayout.Button("512", EditorStyles.miniButtonMid)) { textureWidth = 512; } if (GUILayout.Button("1024", EditorStyles.miniButtonRight)) { textureWidth = 1024; } EditorGUILayout.EndHorizontal(); } else if (isRamp2d) { GUILayout.BeginHorizontal(); textureWidth = EditorGUILayout.IntField("TEXTURE SIZE:", textureWidth); GUILayout.Label("x"); textureHeight = EditorGUILayout.IntField(GUIContent.none, textureHeight); GUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("64", EditorStyles.miniButtonLeft)) { textureWidth = 64; } if (GUILayout.Button("128", EditorStyles.miniButtonMid)) { textureWidth = 128; } if (GUILayout.Button("256", EditorStyles.miniButtonMid)) { textureWidth = 256; } if (GUILayout.Button("512", EditorStyles.miniButtonMid)) { textureWidth = 512; } if (GUILayout.Button("1024", EditorStyles.miniButtonRight)) { textureWidth = 1024; } GUILayout.Space(8); if (GUILayout.Button("64", EditorStyles.miniButtonLeft)) { textureHeight = 64; } if (GUILayout.Button("128", EditorStyles.miniButtonMid)) { textureHeight = 128; } if (GUILayout.Button("256", EditorStyles.miniButtonMid)) { textureHeight = 256; } if (GUILayout.Button("512", EditorStyles.miniButtonMid)) { textureHeight = 512; } if (GUILayout.Button("1024", EditorStyles.miniButtonRight)) { textureHeight = 1024; } EditorGUILayout.EndHorizontal(); } } if (GUI.changed) { serializedObject.ApplyModifiedProperties(); mGradient.alphaKeys = new[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }; if (editMode) { textureIsDirty = true; //Update linked texture if (editedTextureIs2d) { GradientManager.SetPixelsFromGradients(linkedTexture, m2dGradients, linkedTexture.width, linkedTexture.height); } else { var pixels = GradientManager.GetPixelsFromGradient(mGradient, linkedTexture.width, linkedTexture.height); linkedTexture.SetPixels(pixels); linkedTexture.Apply(true, false); } } } GUILayout.Space(8f); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (editMode) { if (GUILayout.Button("Discard", GUILayout.Width(90f), GUILayout.Height(20f))) { DiscardEditedTexture(); if (editModeFromMaterial) { Close(); } else { OpenTool(); } } if (GUILayout.Button("Apply", GUILayout.Width(90f), GUILayout.Height(20f))) { SaveEditedTexture(); if (editModeFromMaterial) { Close(); } else { OpenTool(); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); } var saveButton = false; EditorGUI.BeginDisabledGroup(isRamp2d && (m2dGradients == null || m2dGradients.Length < 2)); if (editMode) { saveButton = GUILayout.Button("Save as...", EditorStyles.miniButton, GUILayout.Width(120f), GUILayout.Height(16f)); } else { saveButton = GUILayout.Button("GENERATE", GUILayout.Width(120f), GUILayout.Height(34f)); } EditorGUI.EndDisabledGroup(); if (saveButton) { var path = EditorUtility.SaveFilePanel("Save Generated Ramp", GradientManager.LAST_SAVE_PATH, editMode ? linkedTexture.name : "TCP2_CustomRamp", "png"); if (!string.IsNullOrEmpty(path)) { GradientManager.LAST_SAVE_PATH = Path.GetDirectoryName(path); var projectPath = path.Replace(Application.dataPath, "Assets"); GenerateAndSaveTexture(projectPath, isRamp2d); if (editMode) { var newTexture = AssetDatabase.LoadAssetAtPath <Texture2D>(projectPath); if (newTexture != null) { foreach (var mat in linkedMaterials) { mat.SetTexture("_Ramp", newTexture); EditorUtility.SetDirty(mat); } } //Reinitialize edit mode InitEditMode(newTexture, linkedMaterials); } } } EditorGUILayout.EndHorizontal(); if (!editMode) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("Load Texture", EditorStyles.miniButton, GUILayout.Width(120f))) { LoadTexture(); } EditorGUILayout.EndHorizontal(); } }
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(); var lW = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 105f; //Avoid refreshing Template meta at every Repaint EditorGUILayout.BeginHorizontal(); var _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 var 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); } 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; TCP2_GUI.Separator(); //######################################################################################################## // 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()) { var 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; var 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))) { var 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; }
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(); } } 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)) { EditorGUILayout.HelpBox(Template.templateInfo, MessageType.Info); } if (!string.IsNullOrEmpty(Template.templateWarning)) { EditorGUILayout.HelpBox(Template.templateWarning, MessageType.Warning); } TCP2_GUI.Separator(); EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); mCurrentShader = EditorGUILayout.ObjectField("Current Shader:", mCurrentShader, typeof(Shader), false) as Shader; if (EditorGUI.EndChangeCheck()) { if (mCurrentShader != null) { LoadCurrentConfigFromShader(mCurrentShader); } } if (GUILayout.Button("Copy Shader", EditorStyles.miniButton, GUILayout.Width(78f))) { CopyShader(); } if (GUILayout.Button("New Shader", EditorStyles.miniButton, GUILayout.Width(76f))) { NewShader(); } EditorGUILayout.EndHorizontal(); 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; if (mCurrentConfig == null) { NewShader(); } //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); } 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(); 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); } } 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 path = EditorUtility.OpenFolderPanel("Choose custom output directory for TCP2 generated shaders", Application.dataPath, ""); if (!string.IsNullOrEmpty(path)) { bool validPath = TCP2_Utils.SystemToUnityPath(ref path); if (validPath) { if (path == "Assets") { TCP2_ShaderGeneratorUtils.OutputPath = "/"; } else { TCP2_ShaderGeneratorUtils.OutputPath = path.Substring("Assets/".Length); } } else { EditorApplication.Beep(); EditorUtility.DisplayDialog("Invalid Path", "The selected path is invalid.\n\nPlease select a folder inside the \"Assets\" folder of your project!", "Ok"); } } } } 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; }
void OnGUI() { TCP2_GUI.UseNewHelpIcon = true; EditorGUILayout.BeginHorizontal(); TCP2_GUI.HeaderBig("TCP 2 - SMOOTHED NORMALS UTILITY"); TCP2_GUI.HelpButton("Smoothed Normals Utility"); EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); TCP2_GUI.UseNewHelpIcon = false; /* * mFormat = EditorGUILayout.TextField(new GUIContent("Axis format", "Normals axis may need to be swapped before being packed into vertex colors/tangent/uv2 data. See documentation for more information."), mFormat); * mFormat = Regex.Replace(mFormat, @"[^xyzXYZ-]", ""); * EditorGUILayout.BeginHorizontal(); * GUILayout.Label("Known formats:"); * if(GUILayout.Button("XYZ", EditorStyles.miniButtonLeft)) { mFormat = "XYZ"; GUI.FocusControl(null); } * if(GUILayout.Button("-YZ-X", EditorStyles.miniButtonMid)) { mFormat = "-YZ-X"; GUI.FocusControl(null); } * if(GUILayout.Button("-Z-Y-X", EditorStyles.miniButtonRight)) { mFormat = "-Z-Y-X"; GUI.FocusControl(null); } * EditorGUILayout.EndHorizontal(); */ if (mMeshes != null && mMeshes.Count > 0) { GUILayout.Space(4); TCP2_GUI.Header("Meshes ready to be processed:", null, true); mScroll = EditorGUILayout.BeginScrollView(mScroll); TCP2_GUI.SeparatorSimple(); bool hasSkinnedMeshes = false; foreach (var sm in mMeshes.Values) { GUILayout.Space(2); GUILayout.BeginHorizontal(); var label = sm.name; if (label.Contains(mFilenameSuffix)) { label = label.Replace(mFilenameSuffix, "\n" + mFilenameSuffix); } GUILayout.Label(label, EditorStyles.wordWrappedMiniLabel, GUILayout.Width(260)); sm.isSkinned = GUILayout.Toggle(sm.isSkinned, new GUIContent(" Skinned", "Should be checked if the mesh will be used on a SkinnedMeshRenderer")); hasSkinnedMeshes |= sm.isSkinned; GUILayout.Space(6); GUILayout.EndHorizontal(); GUILayout.Space(2); TCP2_GUI.SeparatorSimple(); } EditorGUILayout.EndScrollView(); GUILayout.FlexibleSpace(); if (hasSkinnedMeshes) { EditorGUILayout.HelpBox("Smoothed Normals for Skinned meshes will be stored in Tangents only. See Help to know why.", MessageType.Warning); } if (GUILayout.Button(mMeshes.Count == 1 ? "Generate Smoothed Mesh" : "Generate Smoothed Meshes", GUILayout.Height(30))) { try { var selection = new List <Object>(); float progress = 1; float total = mMeshes.Count; foreach (var sm in mMeshes.Values) { if (sm == null) { continue; } EditorUtility.DisplayProgressBar("Hold On", (mMeshes.Count > 1 ? "Generating Smoothed Meshes:\n" : "Generating Smoothed Mesh:\n") + sm.name, progress / total); progress++; Object o = CreateSmoothedMeshAsset(sm); if (o != null) { selection.Add(o); } } Selection.objects = selection.ToArray(); } finally { EditorUtility.ClearProgressBar(); } } } else { EditorGUILayout.HelpBox("Select one or multiple meshes to create a smoothed normals version.\n\nYou can also select models directly in the Scene, the new mesh will automatically be assigned.", MessageType.Info); GUILayout.FlexibleSpace(); using (new EditorGUI.DisabledScope(true)) GUILayout.Button("Generate Smoothed Mesh", GUILayout.Height(30)); } TCP2_GUI.Separator(); smoothedNormalChannel = (Utils.SmoothedNormalsChannel)EditorGUILayout.EnumPopup(TCP2_GUI.TempContent("Vertex Data Target", "Defines where to store the smoothed normals in the mesh; use a target where there isn't any data already."), smoothedNormalChannel); EditorGUI.BeginDisabledGroup(smoothedNormalChannel == Utils.SmoothedNormalsChannel.Tangents || smoothedNormalChannel == Utils.SmoothedNormalsChannel.VertexColors); smoothedNormalUVType = (Utils.SmoothedNormalsUVType)EditorGUILayout.EnumPopup(TCP2_GUI.TempContent("UV Data Type", "Defines where and how to store the smoothed normals in the target vertex UV channel."), smoothedNormalUVType); EditorGUI.EndDisabledGroup(); EditorGUILayout.HelpBox("You will need to select the proper option in the Material Inspector depending on the selected target/format!", MessageType.Info); /* * if (smoothedNormalChannel == Utils.SmoothedNormalsChannel.UV1 || smoothedNormalChannel == Utils.SmoothedNormalsChannel.UV3 || smoothedNormalChannel == Utils.SmoothedNormalsChannel.UV4 || * (smoothedNormalChannel == Utils.SmoothedNormalsChannel.UV2 && smoothedNormalUVType != Utils.SmoothedNormalsUVType.CompressedXY)) * { * EditorGUILayout.HelpBox("Only shaders made with the Shader Generator 2 support all texture coordinates.\nOther shaders only support UV2 with 'Compressed XY' option. UV1, UV3, UV4 won't work with them, as well as 'Full XYZ' and 'Compressed ZW' data types.", MessageType.Warning); * } */ TCP2_GUI.Separator(); TCP2_GUI.Header("Options", null, true); mFilenameSuffix = EditorGUILayout.TextField(TCP2_GUI.TempContent("File name suffix"), mFilenameSuffix); mAlwaysOverwrite = EditorGUILayout.Toggle(new GUIContent("Always Overwrite", "Will always overwrite existing [TCP2 Smoothed] meshes"), mAlwaysOverwrite); mCustomDirectory = EditorGUILayout.Toggle(new GUIContent("Custom Output Directory", "Save the generated smoothed meshes in a custom directory"), mCustomDirectory); using (new EditorGUI.DisabledScope(!mCustomDirectory)) { EditorGUILayout.BeginHorizontal(); mCustomDirectoryPath = EditorGUILayout.TextField(GUIContent.none, mCustomDirectoryPath); if (GUILayout.Button("Select...", EditorStyles.miniButton, GUILayout.ExpandWidth(false))) { var outputPath = Utils.OpenFolderPanel_ProjectPath("Choose custom output directory for generated smoothed meshes", mCustomDirectoryPath); if (!string.IsNullOrEmpty(outputPath)) { mCustomDirectoryPath = outputPath; } } EditorGUILayout.EndHorizontal(); }; GUILayout.Space(10); }
bool ITerrainLayerCustomUI.OnTerrainLayerGUI(TerrainLayer terrainLayer, Terrain terrain) { if (terrain.materialTemplate == null) { return(false); } bool updatedTimestamp = SG2Timestamp != ShaderGenerator2.LastCompilationTimestamp; if (terrainShader != terrain.materialTemplate.shader || updatedTimestamp) { SG2Timestamp = ShaderGenerator2.LastCompilationTimestamp; terrainShader = terrain.materialTemplate.shader; FindUsedTerrainProperties(terrainShader); } if (currentTerrainLayer != terrainLayer || updatedTimestamp) { currentTerrainLayer = terrainLayer; foreach (var terrainLayerProperty in terrainLayerProperties) { terrainLayerProperty.FetchValuesFromTerrainLayer(currentTerrainLayer); } } // Header var label = (Screen.width > 450f) ? "TOONY COLORS PRO 2 - Terrain Layer" : "TCP2 - Terrain Layer"; TCP2_GUI.HeaderBig(label); // Diffuse texture terrainLayer.diffuseTexture = EditorGUILayout.ObjectField(TCP2_GUI.TempContent("Albedo"), terrainLayer.diffuseTexture, typeof(Texture2D), false) as Texture2D; TerrainLayerUtility.ValidateDiffuseTextureUI(terrainLayer.diffuseTexture); // TerrainLayerUtility.TilingSettingsUI(terrainLayer); TCP2_GUI.Header("Tiling Settings"); terrainLayer.tileSize = EditorGUILayout.Vector2Field(TCP2_GUI.TempContent("Size"), terrainLayer.tileSize); terrainLayer.tileOffset = EditorGUILayout.Vector2Field(TCP2_GUI.TempContent("Offset"), terrainLayer.tileOffset); GUILayout.Space(8f); // Custom properties if (terrainLayerProperties.Count > 0) { TCP2_GUI.Header("Custom Properties"); foreach (var terrainLayerProperty in terrainLayerProperties) { EditorGUI.BeginChangeCheck(); { terrainLayerProperty.DrawGUI(terrainLayer); } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(terrainLayer, "Change terrain layer properties"); terrainLayerProperty.TransferValueToTerrainLayer(terrainLayer); } } } return(true); }
void OnGUI() { EditorGUILayout.BeginHorizontal(); TCP2_GUI.HeaderBig(editMode ? "TCP 2 - RAMP EDITOR" : "TCP 2 - RAMP GENERATOR"); TCP2_GUI.HelpButton("Ramp Generator"); EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); if(editMode) { var msg = "This will affect <b>all materials</b> that use this texture!" + (editModeFromMaterial ? "\n\nSave as a new texture first if you want to affect this material only." : "\n\nSave as a new texture if you want to keep the original ramp."); EditorGUILayout.LabelField(GUIContent.none, new GUIContent(msg, TCP2_GUI.GetHelpBoxIcon(MessageType.Warning)), TCP2_GUI.HelpBoxRichTextStyle); var rect = EditorGUILayout.GetControlRect(GUILayout.Height(16f)); var lw = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = 50f; var enabled = GUI.enabled; GUI.enabled = false; EditorGUI.ObjectField(rect, "Editing: ", linkedTexture, typeof(Texture2D), false); EditorGUIUtility.labelWidth = lw; GUI.enabled = enabled; } GUILayout.Label("Click on the gradient to edit it:"); var so = new SerializedObject(this); var sp = so.FindProperty("mGradient"); EditorGUILayout.PropertyField(sp, GUIContent.none); if(!editMode) { textureWidth = EditorGUILayout.IntField("TEXTURE SIZE:", textureWidth); EditorGUILayout.BeginHorizontal(); if(GUILayout.Button("64", EditorStyles.miniButtonLeft)) textureWidth = 64; if(GUILayout.Button("128", EditorStyles.miniButtonMid)) textureWidth = 128; if(GUILayout.Button("256", EditorStyles.miniButtonMid)) textureWidth = 256; if(GUILayout.Button("512", EditorStyles.miniButtonMid)) textureWidth = 512; if(GUILayout.Button("1024", EditorStyles.miniButtonRight)) textureWidth = 1024; EditorGUILayout.EndHorizontal(); } if (GUI.changed) { so.ApplyModifiedProperties(); mGradient.alphaKeys = new[] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(1f, 1f) }; if(editMode) { textureEdited = true; //Update linked texture var pixels = TCP2_GradientManager.GetPixelsFromGradient(mGradient, linkedTexture.width); linkedTexture.SetPixels(pixels); linkedTexture.Apply(true, false); } } GUILayout.Space(8f); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if(editMode) { if(GUILayout.Button("Discard", GUILayout.Width(90f), GUILayout.Height(20f))) { DiscardEditedTexture(); if(editModeFromMaterial) Close(); else OpenTool(); } if(GUILayout.Button("Apply", GUILayout.Width(90f), GUILayout.Height(20f))) { SaveEditedTexture(); if(editModeFromMaterial) Close(); else OpenTool(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); } var saveButton = false; if(editMode) saveButton = GUILayout.Button("Save as...", EditorStyles.miniButton, GUILayout.Width(120f), GUILayout.Height(16f)); else saveButton = GUILayout.Button("GENERATE", GUILayout.Width(120f), GUILayout.Height(34f)); if(saveButton) { var path = EditorUtility.SaveFilePanel("Save Generated Ramp", TCP2_GradientManager.LAST_SAVE_PATH, editMode ? linkedTexture.name : "TCP2_CustomRamp", "png"); if(!string.IsNullOrEmpty(path)) { TCP2_GradientManager.LAST_SAVE_PATH = Path.GetDirectoryName(path); var projectPath = path.Replace(Application.dataPath, "Assets"); GenerateAndSaveTexture(projectPath); if(editMode) { var newtexture = AssetDatabase.LoadAssetAtPath<Texture2D>(projectPath); if(newtexture != null) { foreach(var mat in linkedMaterials) { mat.SetTexture("_Ramp", newtexture); EditorUtility.SetDirty(mat); } } //Reinitialize edit mode InitEditMode(newtexture, linkedMaterials); } } } EditorGUILayout.EndHorizontal(); if(!editMode) { EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if(GUILayout.Button("Load Texture", EditorStyles.miniButton, GUILayout.Width(120f))) { LoadTexture(); } EditorGUILayout.EndHorizontal(); } }
void OnGUI() { 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; EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); mCurrentShader = EditorGUILayout.ObjectField("Current Shader:", mCurrentShader, typeof(Shader), false) as Shader; if (EditorGUI.EndChangeCheck()) { if (mCurrentShader != null) { LoadCurrentConfigFromShader(mCurrentShader); } } if (GUILayout.Button("Copy Shader", EditorStyles.miniButton, GUILayout.Width(78f))) { CopyShader(); } if (GUILayout.Button("New Shader", EditorStyles.miniButton, GUILayout.Width(76f))) { NewShader(); } EditorGUILayout.EndHorizontal(); if (mIsModified) { 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; } } } Template = EditorGUILayout.ObjectField("Template:", Template, typeof(TextAsset), false) as TextAsset; EditorGUIUtility.labelWidth = lW; if (mCurrentConfig == null) { NewShader(); } mGUIEnabled = GUI.enabled; //Name & Filename TCP2_GUI.Header("NAME"); 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() && mAutoNames) { AutoNames(); } GUI.enabled &= !mAutoNames; 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 = mGUIEnabled; Space(); //######################################################################################################## // FEATURES TCP2_GUI.Header("FEATURES"); //Scroll view mScrollPosition = EditorGUILayout.BeginScrollView(mScrollPosition); EditorGUI.BeginChangeCheck(); #if DEBUG_MODE //Custom Lighting GUISingleFeature("CUSTOM_LIGHTING_FORCE", "Custom Lighting", "Use an inline custom lighting model, allowing more flexibility per shader over lighting"); GUISingleFeature("VERTEX_FUNC", "Vertex Function", "Force custom vertex function in surface shader"); Space(); //---------------------------------------------------------------- #endif //Ramp GUIMultipleFeatures("Ramp Style", "Defines the transitioning between dark and lit areas of the model", "Slider Ramp|", "Texture Ramp|TEXTURE_RAMP"); //Textured Threshold GUISingleFeature("TEXTURED_THRESHOLD", "Textured Threshold", "Adds a textured variation to the highlight/shadow threshold, allowing handpainting like effects for example"); Space(); //---------------------------------------------------------------- //Detail GUISingleFeature("DETAIL_TEX", "Detail Texture"); //Detail UV2 GUISingleFeature("DETAIL_UV2", "Use UV2 coordinates", "Use second texture coordinates for the detail texture", HasFeat("DETAIL_TEX"), true); GUIMask("Detail Mask", null, "DETAIL_MASK", "DETAIL_MASK_CHANNEL", "DETAIL_MASK", HasFeatOr("DETAIL_TEX"), true); Space(); //---------------------------------------------------------------- //Color Mask GUIMask("Color Mask", "Adds a mask to the main Color", "COLORMASK", "COLORMASK_CHANNEL", "COLORMASK", true, helpTopic: "Color Mask"); Space(); //---------------------------------------------------------------- //Vertex Colors GUISingleFeature("VCOLORS", "Vertex Colors", "Multiplies the color with vertex colors"); //Texture Blend GUISingleFeature("VCOLORS_BLENDING", "Vertex Texture Blending", "Enables 2-way texture blending based on the mesh's vertex color alpha"); Space(); //---------------------------------------------------------------- //Self-Illumination GUIMask("Self-Illumination Map", null, "ILLUMIN_MASK", "ILLUMIN_MASK_CHANNEL", "ILLUMINATION", helpTopic: "Self-Illumination Map"); //Self-Illumination Color GUISingleFeature("ILLUM_COLOR", "Self-Illumination Color", null, HasFeat("ILLUMINATION"), true); Space(); //---------------------------------------------------------------- //Bump GUISingleFeature("BUMP", "Normal/Bump map", helpTopic: "normal_bump_map_sg"); //Parallax GUISingleFeature("PARALLAX", "Parallax/Height map", null, HasFeat("BUMP"), true); Space(); //---------------------------------------------------------------- //Occlusion // GUISingleFeature("OCCLUSION", "Occlusion Map", "Use an Occlusion Map that will be multiplied with the Ambient lighting"); //Occlusion RGB // GUISingleFeature("OCCL_RGB", "Use RGB map", "Use the RGB channels for Occlusion Map if enabled, use Alpha channel is disabled", HasFeat("OCCLUSION"), true); // Space(); //---------------------------------------------------------------- //Specular GUIMultipleFeaturesHelp("Specular", null, "specular_sg", "Off|", "Regular|SPECULAR", "Anisotropic|SPECULAR_ANISOTROPIC"); if (HasFeatAnd("FORCE_SM2", "SPECULAR_ANISOTROPIC")) { EditorGUILayout.HelpBox("Anisotropic Specular will not compile with Shader Model 2!\n(too many instructions used)", MessageType.Warning); } //Specular Mask GUIMask("Specular Mask", "Enables specular mask (gloss map)", "SPEC_MASK", "SPEC_MASK_CHANNEL", "SPECULAR_MASK", HasFeatOr("SPECULAR", "SPECULAR_ANISOTROPIC"), true); //Specular Shininess Mask GUIMask("Shininess Mask", null, "SPEC_SHIN_MASK", "SPEC_SHIN_MASK_CHANNEL", "SPEC_SHIN_MASK", HasFeatOr("SPECULAR", "SPECULAR_ANISOTROPIC"), true); //Cartoon Specular GUISingleFeature("SPECULAR_TOON", "Cartoon Specular", "Enables clear delimitation of specular color", HasFeatOr("SPECULAR", "SPECULAR_ANISOTROPIC"), true); Space(); //---------------------------------------------------------------- //Reflection GUISingleFeature("REFLECTION", "Reflection", "Enables cubemap reflection", helpTopic: "reflection_sg"); //Reflection Mask GUIMask("Reflection Mask", null, "REFL_MASK", "REFL_MASK_CHANNEL", "REFL_MASK", HasFeatOr("REFLECTION"), true); #if UNITY_5 //Unity5 Reflection Probes GUISingleFeature("U5_REFLPROBE", "Reflection Probes (Unity5)", "Pick reflection from Unity 5 Reflection Probes", HasFeat("REFLECTION"), true, helpTopic: "Reflection Probes"); #endif //Reflection Color GUISingleFeature("REFL_COLOR", "Reflection Color", "Enables reflection color control", HasFeat("REFLECTION"), true); //Reflection Roughness GUISingleFeature("REFL_ROUGH", "Reflection Roughness", "Simulates reflection roughness using the Cubemap's LOD levels\n\nREQUIRES MipMaps ENABLED IN THE CUBEMAP TEXTURE!", HasFeat("REFLECTION") && !HasFeat("U5_REFLPROBE"), true); //Rim Reflection GUISingleFeature("RIM_REFL", "Rim Reflection/Fresnel", "Reflection will be multiplied by rim lighting, resulting in a fresnel-like effect", HasFeat("REFLECTION"), true); Space(); //---------------------------------------------------------------- //Cubemap Ambient GUIMultipleFeaturesInternal("Custom Ambient", "Custom ambient lighting", new string[] { "Off|", "Cubemap Ambient|CUBE_AMBIENT", "Directional Ambient|DIRAMBIENT" }); Space(); //---------------------------------------------------------------- //Independent Shadows GUISingleFeature("INDEPENDENT_SHADOWS", "Independent Shadows", "Disable shadow color influence for cast shadows"); Space(); //---------------------------------------------------------------- //Rim GUIMultipleFeaturesInternal("Rim", "Rim effects (fake light coming from behind the model)", new string[] { "Off|", "Rim Lighting|RIM", "Rim Outline|RIM_OUTLINE" }, !(HasFeatAnd("REFLECTION", "RIM_REFL")), false, "rim_sg"); if (HasFeat("REFLECTION") && HasFeat("RIM_REFL")) { TCP2_ShaderGeneratorUtils.ToggleSingleFeature(mCurrentConfig.Features, "RIM", true); } //Vertex Rim GUISingleFeature("RIM_VERTEX", "Vertex Rim", "Compute rim lighting per-vertex (faster but innacurate)", HasFeatOr("RIM", "RIM_OUTLINE"), true); //Directional Rim GUISingleFeature("RIMDIR", "Directional Rim", null, HasFeatOr("RIM", "RIM_OUTLINE"), true); //Rim Mask GUIMask("Rim Mask", null, "RIM_MASK", "RIM_MASK_CHANNEL", "RIM_MASK", HasFeatOr("RIM", "RIM_OUTLINE"), true); Space(); //---------------------------------------------------------------- //MatCap GUIMultipleFeaturesHelp("MatCap", "MatCap effects (fast fake reflection using a spherical texture)", "matcap_sg", "Off|", "MatCap Add|MATCAP_ADD", "MatCap Multiply|MATCAP_MULT"); //MatCap Mask GUIMask("MatCap Mask", null, "MASK_MC", "MASK_MC_CHANNEL", "MASK_MC", HasFeatOr("MATCAP_ADD", "MATCAP_MULT"), true); //MatCap Pixel GUISingleFeature("MATCAP_PIXEL", "Pixel MatCap", "If enabled, will calculate MatCap per-pixel\nRequires normal map", HasFeat("BUMP") && HasFeatOr("MATCAP_ADD", "MATCAP_MULT"), true); //MatCap Color GUISingleFeature("MC_COLOR", "MatCap Color", null, HasFeatOr("MATCAP_ADD", "MATCAP_MULT"), true); Space(); //---------------------------------------------------------------- //Sketch GUIMultipleFeatures("Sketch", "Sketch texture overlay on the shadowed areas\nOverlay: regular texture overlay\nGradient: used for halftone-like effects", "Off|", "Sketch Overlay|SKETCH", "Sketch Gradient|SKETCH_GRADIENT"); //Sketch Blending GUIMultipleFeaturesInternal("Sketch Blending", "Defines how to blend the Sketch texture with the model", new string[] { "Regular|", "Color Burn|SKETCH_COLORBURN" }, HasFeat("SKETCH") && !HasFeat("SKETCH_GRADIENT"), true, null, false, 166); //Sketch Anim GUISingleFeature("SKETCH_ANIM", "Animated Sketch", "Animates the sketch overlay texture, simulating a hand-drawn animation style", HasFeatOr("SKETCH", "SKETCH_GRADIENT"), true); //Sketch Vertex GUISingleFeature("SKETCH_VERTEX", "Vertex Coords", "Compute screen coordinates in vertex shader (faster but can cause distortions)\nIf disabled will compute in pixel shader (slower)", HasFeatOr("SKETCH", "SKETCH_GRADIENT"), true); //Sketch Scale GUISingleFeature("SKETCH_SCALE", "Scale with model", "If enabled, overlay texture scale will depend on model's distance from view", HasFeatOr("SKETCH", "SKETCH_GRADIENT"), true); Space(); //---------------------------------------------------------------- //Outline GUIMultipleFeatures("Outline", "Outline around the model", "Off|", "Opaque Outline|OUTLINE", "Blended Outline|OUTLINE_BLENDING"); GUISingleFeature("OUTLINE_BEHIND", "Outline behind model", "If enabled, outline will only show behind model", HasFeatOr("OUTLINE", "OUTLINE_BLENDING"), true); Space(); //---------------------------------------------------------------- //Lightmaps GUISingleFeature("LIGHTMAP", "TCP2 Lightmap", "Will use TCP2's lightmap decoding, affecting it with ramp and color settings", helpTopic: "Lightmap"); Space(); //---------------------------------------------------------------- //Alpha Blending GUISingleFeature("ALPHA", "Alpha Blending"); //Alpha Testing GUISingleFeature("CUTOUT", "Alpha Testing (Cutout)"); Space(); //---------------------------------------------------------------- //Culling int cull = TCP2_ShaderGeneratorUtils.HasFeatures(mCurrentConfig, "CULL_FRONT") ? 1 : TCP2_ShaderGeneratorUtils.HasFeatures(mCurrentConfig, "CULL_OFF") ? 2 : 0; EditorGUILayout.BeginHorizontal(); TCP2_GUI.SubHeader("Culling", "Defines how to cull faces", cull > 0, 166); cull = EditorGUILayout.Popup(cull, new string[] { "Default", "Front", "Off (double-sided)" }); TCP2_ShaderGeneratorUtils.ToggleSingleFeature(mCurrentConfig.Features, "CULL_FRONT", cull == 1); TCP2_ShaderGeneratorUtils.ToggleSingleFeature(mCurrentConfig.Features, "CULL_OFF", cull == 2); EditorGUILayout.EndHorizontal(); Space(); //---------------------------------------------------------------- //######################################################################################################## // FLAGS TCP2_GUI.Header("FLAGS"); GUISingleFlag("addshadow", "Add Shadow Passes", "Force the shader to have the Shadow Caster and Collector passes.\nCan help if shadows don't work properly with the shader"); GUISingleFlag("fullforwardshadows", "Full Forward Shadows", "Enable support for all shadow types in Forward rendering path"); #if UNITY_5 GUISingleFlag("noshadow", "Disable Shadows", "Disables all shadow receiving support in this shader"); GUISingleFlag("nofog", "Disable Fog", "Disables Unity Fog support.\nCan help if you run out of vertex interpolators and don't need lightmaps!"); #endif GUISingleFlag("nolightmap", "Disable Lightmaps", "Disables all lightmapping support in this shader.\nCan help if you run out of vertex interpolators and don't need lightmaps!"); GUISingleFlag("noambient", "Disable Ambient Lighting", "Enable support for all shadow types in Forward rendering path", !HasFeatOr("DIRAMBIENT", "CUBE_AMBIENT", "OCCLUSION")); GUISingleFlag("novertexlights", "Disable Vertex Lighting", "Disable vertex lights and spherical harmonics (light probes)"); GUISingleFeature("FORCE_SM2", "Force Shader Model 2", "Compile with Shader Model 2 target. Useful for (very) old GPU compatibility, but some features may not work with it.", showHelp: false); TCP2_GUI.Header("FLAGS (Mobile-friendly)", null, true); GUISingleFlag("noforwardadd", "One Directional Light", "Use additive lights as vertex lights.\nRecommended for Mobile"); #if UNITY_5 GUISingleFlag("interpolateview", "Vertex View Dir", "Calculate view direction per-vertex instead of per-pixel.\nRecommended for Mobile"); #else GUISingleFlag("approxview", "Vertex View Dir", "Calculate view direction per-vertex instead of per-pixel.\nRecommended for Mobile"); #endif GUISingleFlag("halfasview", "Half as View", "Pass half-direction vector into the lighting function instead of view-direction.\nFaster but inaccurate.\nRecommended for Specular, but use Vertex Rim to optimize Rim Effects instead"); #if DEBUG_MODE TCP2_GUI.SeparatorBig(); GUILayout.BeginHorizontal(); mDebugText = EditorGUILayout.TextField("Debug", 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(); //---------------------------------------------------------------- #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(); #if DEBUG_MODE if (GUILayout.Button("Re-Generate All", GUILayout.Width(120f), GUILayout.Height(30f))) { float progress = 0; float total = mUserShaders.Length; foreach (Shader s in mUserShaders) { progress++; EditorUtility.DisplayProgressBar("Hold On", "Generating Shader: " + s.name, progress / total); mCurrentShader = null; LoadCurrentConfigFromShader(s); if (mCurrentShader != null && mCurrentConfig != null) { TCP2_ShaderGeneratorUtils.Compile(mCurrentConfig, Template.text, false, !mOverwriteConfigs, mIsModified); } } EditorUtility.ClearProgressBar(); } #endif 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; } Shader generatedShader = TCP2_ShaderGeneratorUtils.Compile(mCurrentConfig, Template.text, true, !mOverwriteConfigs, mIsModified); ReloadUserShaders(); if (generatedShader != null) { mDirtyConfig = false; LoadCurrentConfigFromShader(generatedShader); mIsModified = false; } } EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); // OPTIONS TCP2_GUI.Header("OPTIONS"); GUILayout.BeginHorizontal(); mSelectGeneratedShader = GUILayout.Toggle(mSelectGeneratedShader, new GUIContent("Select Generated Shader", "Will select the generated file in the Project view"), GUILayout.Width(180f)); mAutoNames = GUILayout.Toggle(mAutoNames, new GUIContent("Automatic Name", "Will automatically generate the shader filename based on its UI name"), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); mOverwriteConfigs = GUILayout.Toggle(mOverwriteConfigs, new GUIContent("Always overwrite shaders", "Overwrite shaders when generating/updating (no prompt)"), GUILayout.Width(180f)); mHideDisabled = GUILayout.Toggle(mHideDisabled, new GUIContent("Hide disabled fields", "Hide properties settings when they cannot be accessed"), GUILayout.ExpandWidth(false)); GUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); mLoadAllShaders = GUILayout.Toggle(mLoadAllShaders, 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 = mSelectGeneratedShader; }
//-------------------------------------------------------------------------------------------------- public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { mMaterialEditor = materialEditor; #if SHOW_DEFAULT_INSPECTOR base.OnGUI(); return; #else //Header EditorGUILayout.BeginHorizontal(); var label = (Screen.width > 450f) ? "TOONY COLORS PRO 2 - INSPECTOR (Generated Shader)" : (Screen.width > 300f ? "TOONY COLORS PRO 2 - INSPECTOR" : "TOONY COLORS PRO 2"); TCP2_GUI.HeaderBig(label); if (TCP2_GUI.Button(TCP2_GUI.CogIcon, "O", "Open in Shader Generator")) { if (targetMaterial.shader != null) { TCP2_ShaderGenerator.OpenWithShader(targetMaterial.shader); } } EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); //Iterate Shader properties materialEditor.serializedObject.Update(); var mShader = materialEditor.serializedObject.FindProperty("m_Shader"); toggledGroups.Clear(); if (materialEditor.isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null) { //Retina display fix EditorGUIUtility.labelWidth = Utils.ScreenWidthRetina - 120f; EditorGUIUtility.fieldWidth = 64f; EditorGUI.BeginChangeCheck(); EditorGUI.indentLevel++; foreach (var p in properties) { var visible = (toggledGroups.Count == 0 || toggledGroups.Peek()); //Hacky way to separate material inspector properties into foldout groups if (p.name.StartsWith("__BeginGroup")) { //Foldout if (visible) { GUILayout.Space(8f); p.floatValue = EditorGUILayout.Foldout(p.floatValue > 0, p.displayName, TCP2_GUI.FoldoutBold) ? 1 : 0; } EditorGUI.indentLevel++; toggledGroups.Push((p.floatValue > 0) && visible); } else if (p.name.StartsWith("__EndGroup")) { EditorGUI.indentLevel--; toggledGroups.Pop(); GUILayout.Space(8f); } else { //Draw regular property if (visible && (p.flags & (MaterialProperty.PropFlags.PerRendererData | MaterialProperty.PropFlags.HideInInspector)) == MaterialProperty.PropFlags.None) { mMaterialEditor.ShaderProperty(p, p.displayName); } } } EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck()) { materialEditor.PropertiesChanged(); } } #endif // !SHOW_DEFAULT_INSPECTOR #if UNITY_5_5_OR_NEWER TCP2_GUI.Separator(); materialEditor.RenderQueueField(); #endif #if UNITY_5_6_OR_NEWER materialEditor.EnableInstancingField(); #endif }
//-------------------------------------------------------------------------------------------------- public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { _materialEditor = materialEditor; _properties = properties; hasAutoTransparency = System.Array.Exists(_properties, prop => prop.name == PROP_RENDERING_MODE); #if SHOW_DEFAULT_INSPECTOR base.OnGUI(); return; #else //Header EditorGUILayout.BeginHorizontal(); var label = (Screen.width > 450f) ? "TOONY COLORS PRO 2 - INSPECTOR (Generated Shader)" : (Screen.width > 300f ? "TOONY COLORS PRO 2 - INSPECTOR" : "TOONY COLORS PRO 2"); TCP2_GUI.HeaderBig(label); if (TCP2_GUI.Button(TCP2_GUI.CogIcon2, "SG2", "Open in Shader Generator")) { if (targetMaterial.shader != null) { ShaderGenerator2.OpenWithShader(targetMaterial.shader); } } EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); //Iterate Shader properties materialEditor.serializedObject.Update(); var mShader = materialEditor.serializedObject.FindProperty("m_Shader"); toggledGroups.Clear(); // Auto-transparency if (hasAutoTransparency) { int indent = EditorGUI.indentLevel; EditorGUI.indentLevel++; { EditorGUILayout.BeginHorizontal(); { GUILayout.Space(15); GUILayout.Label(TCP2_GUI.TempContent("Transparency"), EditorStyles.boldLabel); } EditorGUILayout.EndHorizontal(); HandleRenderingMode(); } EditorGUI.indentLevel = indent; } if (materialEditor.isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null) { //Retina display fix EditorGUIUtility.labelWidth = Utils.ScreenWidthRetina - 120f; EditorGUIUtility.fieldWidth = 64f; EditorGUI.BeginChangeCheck(); EditorGUI.indentLevel++; foreach (var p in properties) { var visible = (toggledGroups.Count == 0 || toggledGroups.Peek()); //Hacky way to separate material inspector properties into foldout groups if (p.name.StartsWith("__BeginGroup")) { //Foldout if (visible) { GUILayout.Space(2f); Rect propertyRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight, EditorStyles.layerMaskField); propertyRect.x += 12; propertyRect.width -= 12; p.floatValue = EditorGUI.Foldout(propertyRect, p.floatValue > 0, p.displayName, true) ? 1 : 0; } EditorGUI.indentLevel++; toggledGroups.Push((p.floatValue > 0) && visible); } else if (p.name.StartsWith("__EndGroup")) { EditorGUI.indentLevel--; toggledGroups.Pop(); GUILayout.Space(2f); } else { //Draw regular property if (visible && (p.flags & (MaterialProperty.PropFlags.PerRendererData | MaterialProperty.PropFlags.HideInInspector)) == MaterialProperty.PropFlags.None) { _materialEditor.ShaderProperty(p, p.displayName); } } } EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck()) { materialEditor.PropertiesChanged(); } } #endif // !SHOW_DEFAULT_INSPECTOR #if UNITY_5_5_OR_NEWER TCP2_GUI.Separator(); materialEditor.RenderQueueField(); #endif #if UNITY_5_6_OR_NEWER materialEditor.EnableInstancingField(); #endif }
void OnGUI() { EditorGUILayout.BeginHorizontal(); TCP2_GUI.HeaderBig("TCP 2 - SMOOTHED NORMALS UTILITY"); TCP2_GUI.HelpButton("Smoothed Normals Utility"); EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); /* * mFormat = EditorGUILayout.TextField(new GUIContent("Axis format", "Normals axis may need to be swapped before being packed into vertex colors/tangent/uv2 data. See documentation for more information."), mFormat); * mFormat = Regex.Replace(mFormat, @"[^xyzXYZ-]", ""); * EditorGUILayout.BeginHorizontal(); * GUILayout.Label("Known formats:"); * if(GUILayout.Button("XYZ", EditorStyles.miniButtonLeft)) { mFormat = "XYZ"; GUI.FocusControl(null); } * if(GUILayout.Button("-YZ-X", EditorStyles.miniButtonMid)) { mFormat = "-YZ-X"; GUI.FocusControl(null); } * if(GUILayout.Button("-Z-Y-X", EditorStyles.miniButtonRight)) { mFormat = "-Z-Y-X"; GUI.FocusControl(null); } * EditorGUILayout.EndHorizontal(); */ if (mMeshes != null && mMeshes.Count > 0) { GUILayout.Space(4); TCP2_GUI.Header("Meshes ready to be processed:", null, true); mScroll = EditorGUILayout.BeginScrollView(mScroll); TCP2_GUI.GUILine(Color.gray, 1); // for(int i = 0; i < mMeshes.Count; i++) foreach (SelectedMesh sm in mMeshes.Values) { GUILayout.Space(2); GUILayout.BeginHorizontal(); string label = sm.name; if (label.Contains(MESH_SUFFIX)) { label = label.Replace(MESH_SUFFIX, "\n" + MESH_SUFFIX); } GUILayout.Label(label, EditorStyles.wordWrappedMiniLabel, GUILayout.Width(270)); sm.isSkinned = GUILayout.Toggle(sm.isSkinned, new GUIContent("Skinned", "Should be checked if the mesh will be used on a SkinnedMeshRenderer"), EditorStyles.toolbarButton); GUILayout.Space(6); GUILayout.EndHorizontal(); GUILayout.Space(2); TCP2_GUI.GUILine(Color.gray, 1); } EditorGUILayout.EndScrollView(); GUILayout.FlexibleSpace(); if (GUILayout.Button(mMeshes.Count == 1 ? "Generate Smoothed Mesh" : "Generate Smoothed Meshes", GUILayout.Height(30))) { List <Object> selection = new List <Object>(); float progress = 1; float total = mMeshes.Count; foreach (SelectedMesh sm in mMeshes.Values) { if (sm == null) { continue; } EditorUtility.DisplayProgressBar("Hold On", (mMeshes.Count > 1 ? "Generating Smoothed Meshes:\n" : "Generating Smoothed Mesh:\n") + sm.name, progress / total); progress++; Object o = CreateSmoothedMeshAsset(sm); if (o != null) { selection.Add(o); } } EditorUtility.ClearProgressBar(); Selection.objects = selection.ToArray(); } } else { EditorGUILayout.HelpBox("Select one or multiple meshes to create a smoothed normals version.\n\nYou can also select models directly in the Scene, the new mesh will automatically be assigned.", MessageType.Info); GUILayout.FlexibleSpace(); } TCP2_GUI.Header("Store smoothed normals in:", "You will have to select the correct option in the Material Inspector when using outlines", true); int choice = 0; if (mTangents) { choice = 1; } if (mUV2) { choice = 2; } choice = TCP2_GUI.RadioChoice(choice, true, "Vertex Colors", "Tangents", "UV2"); EditorGUILayout.HelpBox("Smoothed Normals for Skinned meshes will be stored in Tangents only. See Help to know why.", MessageType.Warning); mVColors = (choice == 0); mTangents = (choice == 1); mUV2 = (choice == 2); TCP2_GUI.Header("Options", null, true); GUILayout.BeginHorizontal(); mAlwaysOverwrite = EditorGUILayout.Toggle(new GUIContent("Always Overwrite", "Will always overwrite existing [TCP2 Smoothed] meshes"), mAlwaysOverwrite); if (GUILayout.Button(new GUIContent("Clear Progress Bar", "Clears the progress bar if it's hanging on screen after an error."), EditorStyles.miniButton, GUILayout.Width(164))) { EditorUtility.ClearProgressBar(); } GUILayout.EndHorizontal(); }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { mMaterialEditor = materialEditor; #if SHOW_DEFAULT_INSPECTOR base.OnGUI(); return; #else if (mJustChangedShader) { mJustChangedShader = false; mVariantError = null; Event.current.Use(); //Avoid layout mismatch error SceneView.RepaintAll(); } UpdateFeaturesFromShader(); //Get material keywords List <string> keywordsList = new List <string>(targetMaterial.shaderKeywords); bool updateKeywords = false; bool updateVariant = false; //Header EditorGUILayout.BeginHorizontal(); TCP2_GUI.HeaderBig("TOONY COLORS PRO 2 - INSPECTOR"); if (isGeneratedShader && TCP2_GUI.Button(TCP2_GUI.CogIcon, "O", "Open in Shader Generator")) { if (targetMaterial.shader != null) { TCP2_ShaderGenerator.OpenWithShader(targetMaterial.shader); } } TCP2_GUI.HelpButton("Unified Shader"); EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); if (!string.IsNullOrEmpty(mVariantError)) { EditorGUILayout.HelpBox(mVariantError, MessageType.Error); EditorGUILayout.HelpBox("Some of the shaders are packed to avoid super long loading times when you import Toony Colors Pro 2 into Unity.\n\n" + "You can unpack them by category in the menu:\n\"Tools > Toony Colors Pro 2 > Unpack Shaders > ...\"", MessageType.Info); } //Iterate Shader properties materialEditor.serializedObject.Update(); SerializedProperty mShader = materialEditor.serializedObject.FindProperty("m_Shader"); if (materialEditor.isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null) { //Retina display fix EditorGUIUtility.labelWidth = TCP2_Utils.ScreenWidthRetina - 120f; EditorGUIUtility.fieldWidth = 64f; EditorGUI.BeginChangeCheck(); MaterialProperty[] props = properties; //UNFILTERED PARAMETERS ============================================================== TCP2_GUI.HeaderAndHelp("BASE", "Base Properties"); if (ShowFilteredProperties(null, props)) { if (!isGeneratedShader) { TCP2_Utils.ShaderKeywordToggle("TCP2_DISABLE_WRAPPED_LIGHT", "Disable Wrapped Lighting", "Disable wrapped lighting, reducing intensity received from lights", keywordsList, ref updateKeywords, "Disable Wrapped Lighting"); } TCP2_GUI.Separator(); } //FILTERED PARAMETERS ================================================================ //RAMP TYPE -------------------------------------------------------------------------- if (CategoryFilter("TEXTURE_RAMP")) { if (isGeneratedShader) { ShowFilteredProperties("#RAMPT#", props); } else { if (TCP2_Utils.ShaderKeywordToggle("TCP2_RAMPTEXT", "Texture Toon Ramp", "Make the toon ramp based on a texture", keywordsList, ref updateKeywords, "Ramp Style")) { ShowFilteredProperties("#RAMPT#", props); } else { ShowFilteredProperties("#RAMPF#", props); } } } else { ShowFilteredProperties("#RAMPF#", props); } TCP2_GUI.Separator(); //BUMP/NORMAL MAPPING ---------------------------------------------------------------- if (CategoryFilter("BUMP")) { if (isGeneratedShader) { TCP2_GUI.HeaderAndHelp("BUMP/NORMAL MAPPING", "Normal/Bump map"); ShowFilteredProperties("#NORM#", props); ShowFilteredProperties("#PLLX#", props); } else { if (TCP2_Utils.ShaderKeywordToggle("TCP2_BUMP", "BUMP/NORMAL MAPPING", "Enable bump mapping using normal maps", keywordsList, ref updateKeywords, "Normal/Bump map")) { ShowFilteredProperties("#NORM#", props); } } TCP2_GUI.Separator(); } //SPECULAR --------------------------------------------------------------------------- if (CategoryFilter("SPECULAR", "SPECULAR_ANISOTROPIC")) { if (isGeneratedShader) { TCP2_GUI.HeaderAndHelp("SPECULAR", "Specular"); ShowFilteredProperties("#SPEC#", props); if (HasFlags("SPECULAR_ANISOTROPIC")) { ShowFilteredProperties("#SPECA#", props); } if (HasFlags("SPECULAR_TOON")) { ShowFilteredProperties("#SPECT#", props); } } else { bool specular = TCP2_Utils.HasKeywords(keywordsList, "TCP2_SPEC", "TCP2_SPEC_TOON"); TCP2_Utils.ShaderVariantUpdate("Specular", ShaderVariants, ShaderVariantsEnabled, specular, ref updateVariant); specular |= TCP2_Utils.ShaderKeywordRadio("SPECULAR", new string[] { "TCP2_SPEC_OFF", "TCP2_SPEC", "TCP2_SPEC_TOON" }, new GUIContent[] { new GUIContent("Off", "No Specular"), new GUIContent("Regular", "Default Blinn-Phong Specular"), new GUIContent("Cartoon", "Specular with smoothness control") }, keywordsList, ref updateKeywords); if (specular) { ShowFilteredProperties("#SPEC#", props); bool specr = TCP2_Utils.HasKeywords(keywordsList, "TCP2_SPEC_TOON"); if (specr) { ShowFilteredProperties("#SPECT#", props); } } } TCP2_GUI.Separator(); } //REFLECTION ------------------------------------------------------------------------- if (CategoryFilter("REFLECTION") && !isMobileShader) { if (isGeneratedShader) { TCP2_GUI.HeaderAndHelp("REFLECTION", "Reflection"); ShowFilteredProperties("#REFL#", props); #if UNITY_5 if (HasFlags("U5_REFLPROBE")) { ShowFilteredProperties("#REFL_U5#", props); } #endif if (HasFlags("REFL_COLOR")) { ShowFilteredProperties("#REFLC#", props); } if (HasFlags("REFL_ROUGH")) { ShowFilteredProperties("#REFLR#", props); EditorGUILayout.HelpBox("Cubemap Texture needs to have MipMaps enabled for Roughness to work!", MessageType.Info); } } else { bool reflection = TCP2_Utils.HasKeywords(keywordsList, "TCP2_REFLECTION", "TCP2_REFLECTION_MASKED"); TCP2_Utils.ShaderVariantUpdate("Reflection", ShaderVariants, ShaderVariantsEnabled, reflection, ref updateVariant); reflection |= TCP2_Utils.ShaderKeywordRadio("REFLECTION", new string[] { "TCP2_REFLECTION_OFF", "TCP2_REFLECTION", "TCP2_REFLECTION_MASKED" }, new GUIContent[] { new GUIContent("Off", "No Cubemap Reflection"), new GUIContent("Global", "Global Cubemap Reflection"), new GUIContent("Masked", "Masked Cubemap Reflection (using the main texture's alpha channel)") }, keywordsList, ref updateKeywords); if (reflection) { #if UNITY_5 //Reflection Probes toggle if (TCP2_Utils.ShaderKeywordToggle("TCP2_U5_REFLPROBE", "Use Reflection Probes", "Use Unity 5's Reflection Probes", keywordsList, ref updateKeywords)) { ShowFilteredProperties("#REFL_U5#", props); } #endif ShowFilteredProperties("#REFL#", props); } } TCP2_GUI.Separator(); } //MATCAP ----------------------------------------------------------------------------- if (CategoryFilter("MATCAP")) { if (isGeneratedShader) { TCP2_GUI.Header("MATCAP"); ShowFilteredProperties("#MC#", props); TCP2_GUI.Separator(); } else if (isMobileShader) { bool matcap = TCP2_Utils.HasKeywords(keywordsList, "TCP2_MC", "TCP2_MCMASK"); TCP2_Utils.ShaderVariantUpdate("Matcap", ShaderVariants, ShaderVariantsEnabled, matcap, ref updateVariant); matcap |= TCP2_Utils.ShaderKeywordRadio("MATCAP", new string[] { "TCP2_MC_OFF", "TCP2_MC", "TCP2_MCMASK" }, new GUIContent[] { new GUIContent("Off", "No MatCap reflection"), new GUIContent("Global", "Global additive MatCap"), new GUIContent("Masked", "Masked additive MatCap (using the main texture's alpha channel)") }, keywordsList, ref updateKeywords); if (matcap) { ShowFilteredProperties("#MC#", props); } TCP2_GUI.Separator(); } } //SUBSURFACE SCATTERING -------------------------------------------------------------------------------- if (CategoryFilter("SUBSURFACE_SCATTERING") && isGeneratedShader) { TCP2_GUI.HeaderAndHelp("SUBSURFACE SCATTERING", "Subsurface Scattering"); ShowFilteredProperties("#SUBS#", props); TCP2_GUI.Separator(); } //RIM -------------------------------------------------------------------------------- if (CategoryFilter("RIM", "RIM_OUTLINE")) { if (isGeneratedShader) { TCP2_GUI.HeaderAndHelp("RIM", "Rim"); ShowFilteredProperties("#RIM#", props); if (HasFlags("RIMDIR")) { ShowFilteredProperties("#RIMDIR#", props); if (HasFlags("PARALLAX")) { EditorGUILayout.HelpBox("Because it affects the view direction vector, Rim Direction may distort Parallax effect.", MessageType.Warning); } } } else { bool rim = TCP2_Utils.HasKeywords(keywordsList, "TCP2_RIM"); bool rimOutline = TCP2_Utils.HasKeywords(keywordsList, "TCP2_RIMO"); TCP2_Utils.ShaderVariantUpdate("Rim", ShaderVariants, ShaderVariantsEnabled, rim, ref updateVariant); TCP2_Utils.ShaderVariantUpdate("RimOutline", ShaderVariants, ShaderVariantsEnabled, rimOutline, ref updateVariant); rim |= rimOutline |= TCP2_Utils.ShaderKeywordRadio("RIM", new string[] { "TCP2_RIM_OFF", "TCP2_RIM", "TCP2_RIMO" }, new GUIContent[] { new GUIContent("Off", "No Rim effect"), new GUIContent("Lighting", "Rim lighting (additive)"), new GUIContent("Outline", "Rim outline (blended)") }, keywordsList, ref updateKeywords); if (rim || rimOutline) { ShowFilteredProperties("#RIM#", props); if (CategoryFilter("RIMDIR")) { if (TCP2_Utils.ShaderKeywordToggle("TCP2_RIMDIR", "Directional Rim", "Enable directional rim control (rim calculation is approximated if enabled)", keywordsList, ref updateKeywords)) { ShowFilteredProperties("#RIMDIR#", props); } } } } TCP2_GUI.Separator(); } //CUBEMAP AMBIENT -------------------------------------------------------------------- if (CategoryFilter("CUBE_AMBIENT") && isGeneratedShader) { TCP2_GUI.HeaderAndHelp("CUBEMAP AMBIENT", "Cubemap Ambient"); ShowFilteredProperties("#CUBEAMB#", props); TCP2_GUI.Separator(); } //DIRECTIONAL AMBIENT -------------------------------------------------------------------- if (CategoryFilter("DIRAMBIENT") && isGeneratedShader) { TCP2_GUI.HeaderAndHelp("DIRECTIONAL AMBIENT", "Directional Ambient"); DirectionalAmbientGUI("#DAMB#", props); TCP2_GUI.Separator(); } //SKETCH -------------------------------------------------------------------------------- if (CategoryFilter("SKETCH", "SKETCH_GRADIENT") && isGeneratedShader) { TCP2_GUI.HeaderAndHelp("SKETCH", "Sketch"); bool sketch = HasFlags("SKETCH"); bool sketchG = HasFlags("SKETCH_GRADIENT"); if (sketch || sketchG) { ShowFilteredProperties("#SKETCH#", props); } if (sketchG) { ShowFilteredProperties("#SKETCHG#", props); } TCP2_GUI.Separator(); } //OUTLINE -------------------------------------------------------------------------------- if (CategoryFilter("OUTLINE", "OUTLINE_BLENDING")) { bool hasOutlineOpaque = false; bool hasOutlineBlending = false; bool hasOutline = false; if (isGeneratedShader) { TCP2_GUI.HeaderAndHelp("OUTLINE", "Outline"); hasOutlineOpaque = HasFlags("OUTLINE"); hasOutlineBlending = HasFlags("OUTLINE_BLENDING"); hasOutline = hasOutlineOpaque || hasOutlineBlending; } else { hasOutlineOpaque = TCP2_Utils.HasKeywords(keywordsList, "OUTLINES"); hasOutlineBlending = TCP2_Utils.HasKeywords(keywordsList, "OUTLINE_BLENDING"); hasOutline = hasOutlineOpaque || hasOutlineBlending; TCP2_Utils.ShaderVariantUpdate("Outline", ShaderVariants, ShaderVariantsEnabled, hasOutlineOpaque, ref updateVariant); TCP2_Utils.ShaderVariantUpdate("OutlineBlending", ShaderVariants, ShaderVariantsEnabled, hasOutlineBlending, ref updateVariant); hasOutline |= TCP2_Utils.ShaderKeywordRadio("OUTLINE", new string[] { "OUTLINE_OFF", "OUTLINES", "OUTLINE_BLENDING" }, new GUIContent[] { new GUIContent("Off", "No Outline"), new GUIContent("Opaque", "Opaque Outline"), new GUIContent("Blended", "Allows transparent Outline and other effects") }, keywordsList, ref updateKeywords); } if (hasOutline) { EditorGUI.indentLevel++; //Outline Type --------------------------------------------------------------------------- ShowFilteredProperties("#OUTLINE#", props, false); if (!isMobileShader && !HasFlags("FORCE_SM2")) { bool outlineTextured = TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_TEXTURED", "Outline Color from Texture", "If enabled, outline will take an averaged color from the main texture multiplied by Outline Color", keywordsList, ref updateKeywords); if (outlineTextured) { ShowFilteredProperties("#OUTLINETEX#", props); } } TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_CONST_SIZE", "Constant Size Outline", "If enabled, outline will have a constant size independently from camera distance", keywordsList, ref updateKeywords); if (TCP2_Utils.ShaderKeywordToggle("TCP2_ZSMOOTH_ON", "Correct Z Artefacts", "Enable the outline z-correction to try to hide artefacts from complex models", keywordsList, ref updateKeywords)) { ShowFilteredProperties("#OUTLINEZ#", props); } //Smoothed Normals ----------------------------------------------------------------------- EditorGUI.indentLevel--; TCP2_GUI.Header("OUTLINE NORMALS", "Defines where to take the vertex normals from to draw the outline.\nChange this when using a smoothed mesh to fill the gaps shown in hard-edged meshes."); EditorGUI.indentLevel++; TCP2_Utils.ShaderKeywordRadio(null, new string[] { "TCP2_NONE", "TCP2_COLORS_AS_NORMALS", "TCP2_TANGENT_AS_NORMALS", "TCP2_UV2_AS_NORMALS" }, new GUIContent[] { new GUIContent("Regular", "Use regular vertex normals"), new GUIContent("Vertex Colors", "Use vertex colors as normals (with smoothed mesh)"), new GUIContent("Tangents", "Use tangents as normals (with smoothed mesh)"), new GUIContent("UV2", "Use second texture coordinates as normals (with smoothed mesh)"), }, keywordsList, ref updateKeywords); EditorGUI.indentLevel--; //Outline Blending ----------------------------------------------------------------------- if (hasOutlineBlending) { MaterialProperty[] blendProps = GetFilteredProperties("#BLEND#", props); if (blendProps.Length != 2) { EditorGUILayout.HelpBox("Couldn't find Blending properties!", MessageType.Error); } else { TCP2_GUI.Header("OUTLINE BLENDING", "BLENDING EXAMPLES:\nAlpha Transparency: SrcAlpha / OneMinusSrcAlpha\nMultiply: DstColor / Zero\nAdd: One / One\nSoft Add: OneMinusDstColor / One"); UnityEngine.Rendering.BlendMode blendSrc = (UnityEngine.Rendering.BlendMode)blendProps[0].floatValue; UnityEngine.Rendering.BlendMode blendDst = (UnityEngine.Rendering.BlendMode)blendProps[1].floatValue; EditorGUI.BeginChangeCheck(); float f = EditorGUIUtility.fieldWidth; float l = EditorGUIUtility.labelWidth; EditorGUIUtility.fieldWidth = 110f; EditorGUIUtility.labelWidth -= Mathf.Abs(f - EditorGUIUtility.fieldWidth); blendSrc = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Source Factor", blendSrc); blendDst = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Destination Factor", blendDst); EditorGUIUtility.fieldWidth = f; EditorGUIUtility.labelWidth = l; if (EditorGUI.EndChangeCheck()) { blendProps[0].floatValue = (float)blendSrc; blendProps[1].floatValue = (float)blendDst; } } } } TCP2_GUI.Separator(); } //LIGHTMAP -------------------------------------------------------------------------------- #if UNITY_4_5 if (CategoryFilter("LIGHTMAP") && !isGeneratedShader) { TCP2_Utils.ShaderKeywordRadio("LIGHTMAP", new string[] { "TCP2_LIGHTMAP_OFF", "TCP2_LIGHTMAP" }, new GUIContent[] { new GUIContent("Unity", "Use Unity's built-in lightmap decoding"), new GUIContent("Toony Colors Pro 2", "Use TCP2's lightmap decoding (lightmaps will be affected by ramp and color settings)") }, keywordsList, ref updateKeywords); } #endif //TRANSPARENCY -------------------------------------------------------------------------------- if (CategoryFilter("ALPHA", "CUTOUT") && isGeneratedShader) { bool alpha = false; bool cutout = false; if (isGeneratedShader) { TCP2_GUI.Header("TRANSPARENCY"); alpha = HasFlags("ALPHA"); cutout = HasFlags("CUTOUT"); } if (alpha) { MaterialProperty[] blendProps = GetFilteredProperties("#ALPHA#", props); if (blendProps.Length != 2) { EditorGUILayout.HelpBox("Couldn't find Blending properties!", MessageType.Error); } else { TCP2_GUI.Header("BLENDING", "BLENDING EXAMPLES:\nAlpha Transparency: SrcAlpha / OneMinusSrcAlpha\nMultiply: DstColor / Zero\nAdd: One / One\nSoft Add: OneMinusDstColor / One"); UnityEngine.Rendering.BlendMode blendSrc = (UnityEngine.Rendering.BlendMode)blendProps[0].floatValue; UnityEngine.Rendering.BlendMode blendDst = (UnityEngine.Rendering.BlendMode)blendProps[1].floatValue; EditorGUI.BeginChangeCheck(); float f = EditorGUIUtility.fieldWidth; float l = EditorGUIUtility.labelWidth; EditorGUIUtility.fieldWidth = 110f; EditorGUIUtility.labelWidth -= Mathf.Abs(f - EditorGUIUtility.fieldWidth); blendSrc = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Source Factor", blendSrc); blendDst = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Destination Factor", blendDst); EditorGUIUtility.fieldWidth = f; EditorGUIUtility.labelWidth = l; if (EditorGUI.EndChangeCheck()) { blendProps[0].floatValue = (float)blendSrc; blendProps[1].floatValue = (float)blendDst; } } } if (cutout) { ShowFilteredProperties("#CUTOUT#", props); } } #if DEBUG_INFO //-------------------------------------------------------------------------------------- //DEBUG -------------------------------------------------------------------------------- TCP2_GUI.SeparatorBig(); TCP2_GUI.Header("DEBUG"); //Clear Keywords if (GUILayout.Button("Clear Keywords", EditorStyles.miniButton)) { keywordsList.Clear(); updateKeywords = true; } //Shader Flags GUILayout.Label("Features", EditorStyles.boldLabel); string features = ""; if (mShaderFeatures != null) { foreach (string flag in mShaderFeatures) { features += flag + ", "; } } if (features.Length > 0) { features = features.Substring(0, features.Length - 2); } GUILayout.Label(features, EditorStyles.wordWrappedMiniLabel); //Shader Keywords GUILayout.Label("Keywords", EditorStyles.boldLabel); string keywords = ""; foreach (string keyword in keywordsList) { keywords += keyword + ", "; } if (keywords.Length > 0) { keywords = keywords.Substring(0, keywords.Length - 2); } GUILayout.Label(keywords, EditorStyles.wordWrappedMiniLabel); #endif //-------------------------------------------------------------------------------------- if (EditorGUI.EndChangeCheck()) { materialEditor.PropertiesChanged(); } } //Update Keywords if (updateKeywords) { if (materialEditor.targets != null && materialEditor.targets.Length > 0) { foreach (Object t in materialEditor.targets) { (t as Material).shaderKeywords = keywordsList.ToArray(); EditorUtility.SetDirty(t); } } else { targetMaterial.shaderKeywords = keywordsList.ToArray(); EditorUtility.SetDirty(targetMaterial); } } //Update Variant if (updateVariant && !isGeneratedShader) { string baseName = isMobileShader ? BASE_SHADER_NAME_MOB : BASE_SHADER_NAME; string newShader = baseName; for (int i = 0; i < ShaderVariants.Count; i++) { if (ShaderVariantsEnabled[i]) { newShader += " " + ShaderVariants[i]; } } newShader = newShader.TrimEnd(); //If variant shader string basePath = BASE_SHADER_PATH; if (newShader != baseName) { basePath = VARIANT_SHADER_PATH; } Shader shader = Shader.Find(basePath + newShader); if (shader != null) { materialEditor.SetShader(shader, false); mJustChangedShader = true; } else { if (Event.current.type != EventType.Layout) { mVariantError = "Can't find shader variant:\n" + basePath + newShader; } materialEditor.Repaint(); } } else if (!string.IsNullOrEmpty(mVariantError) && Event.current.type != EventType.Layout) { mVariantError = null; materialEditor.Repaint(); } #endif #if UNITY_5_5_OR_NEWER materialEditor.RenderQueueField(); #endif }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props) { if (InspectorNeedsUpdate) { //reset properties blendMode = null; albedoMap = null; albedoColor = null; alphaCutoff = null; specularMap = null; specularColor = null; metallicMap = null; metallic = null; smoothness = null; smoothnessScale = null; //smoothnessMapChannel = null; bumpScale = null; bumpMap = null; occlusionStrength = null; occlusionMap = null; heigtMapScale = null; heightMap = null; emissionColorForRendering = null; emissionMap = null; detailMask = null; detailAlbedoMap = null; detailNormalMapScale = null; detailNormalMap = null; //uvSetSecondary = null; } FindProperties(props); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly m_MaterialEditor = materialEditor; var material = materialEditor.target as Material; // Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing // material to a standard shader. // Do this before any GUI code has been issued to prevent layout issues in subsequent GUILayout statements (case 780071) if (m_FirstTimeApply || InspectorNeedsUpdate) { MaterialChanged(material, m_WorkflowMode); m_FirstTimeApply = false; InspectorNeedsUpdate = false; } //TCP2 Header EditorGUILayout.BeginHorizontal(); var label = (Screen.width > 450f) ? "TOONY COLORS PRO 2 - INSPECTOR (Generated Shader)" : (Screen.width > 300f ? "TOONY COLORS PRO 2 - INSPECTOR" : "TOONY COLORS PRO 2"); TCP2_GUI.HeaderBig(label); if (TCP2_GUI.Button(TCP2_GUI.CogIcon, "O", "Open in Shader Generator")) { if (material.shader != null) { TCP2_ShaderGenerator.OpenWithShader(material.shader); } } EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); ShaderPropertiesGUI(material); #if UNITY_5_5_OR_NEWER materialEditor.RenderQueueField(); #endif #if UNITY_5_6_OR_NEWER materialEditor.EnableInstancingField(); #endif }
public override void OnInspectorGUI() { if (!this.isVisible) { return; } #if SHOW_DEFAULT_INSPECTOR base.OnInspectorGUI(); return; #else //Detect if Shader has changed if (targetMaterial.shader != mCurrentShader) { mCurrentShader = targetMaterial.shader; } UpdateFeaturesFromShader(); //Get material keywords List <string> keywordsList = new List <string>(targetMaterial.shaderKeywords); bool updateKeywords = false; //Header TCP2_GUI.HeaderBig("TOONY COLORS PRO 2 - Outlines Only"); TCP2_GUI.Separator(); //Iterate Shader properties serializedObject.Update(); SerializedProperty mShader = serializedObject.FindProperty("m_Shader"); if (isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null) { EditorGUIUtility.labelWidth = TCP2_Utils.ScreenWidthRetina - 120f; EditorGUIUtility.fieldWidth = 64f; EditorGUI.BeginChangeCheck(); MaterialProperty[] props = GetMaterialProperties(this.targets); //UNFILTERED PARAMETERS ============================================================== if (ShowFilteredProperties(null, props, false)) { TCP2_GUI.Separator(); } //FILTERED PARAMETERS ================================================================ //Outline Type --------------------------------------------------------------------------- ShowFilteredProperties("#OUTLINE#", props, false); if (!mShaderModel2) { bool texturedOutline = TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_TEXTURED", "Outline Color from Texture", "If enabled, outline will take an averaged color from the main texture multiplied by Outline Color", keywordsList, ref updateKeywords); if (texturedOutline) { ShowFilteredProperties("#OUTLINETEX#", props); } } TCP2_Utils.ShaderKeywordToggle("TCP2_OUTLINE_CONST_SIZE", "Constant Size Outline", "If enabled, outline will have a constant size independently from camera distance", keywordsList, ref updateKeywords); if (TCP2_Utils.ShaderKeywordToggle("TCP2_ZSMOOTH_ON", "Correct Z Artefacts", "Enable the outline z-correction to try to hide artefacts from complex models", keywordsList, ref updateKeywords)) { ShowFilteredProperties("#OUTLINEZ#", props); } //Smoothed Normals ----------------------------------------------------------------------- TCP2_GUI.Header("OUTLINE NORMALS", "Defines where to take the vertex normals from to draw the outline.\nChange this when using a smoothed mesh to fill the gaps shown in hard-edged meshes."); TCP2_Utils.ShaderKeywordRadio(null, new string[] { "TCP2_NONE", "TCP2_COLORS_AS_NORMALS", "TCP2_TANGENT_AS_NORMALS", "TCP2_UV2_AS_NORMALS" }, new GUIContent[] { new GUIContent("Regular", "Use regular vertex normals"), new GUIContent("Vertex Colors", "Use vertex colors as normals (with smoothed mesh)"), new GUIContent("Tangents", "Use tangents as normals (with smoothed mesh)"), new GUIContent("UV2", "Use second texture coordinates as normals (with smoothed mesh)"), }, keywordsList, ref updateKeywords); //Outline Blending ----------------------------------------------------------------------- if (mIsOutlineBlending) { MaterialProperty[] blendProps = GetFilteredProperties("#BLEND#", props); if (blendProps.Length != 2) { EditorGUILayout.HelpBox("Couldn't find Blending properties!", MessageType.Error); } else { TCP2_GUI.Header("OUTLINE BLENDING", "BLENDING EXAMPLES:\nAlpha Transparency: SrcAlpha / OneMinusSrcAlpha\nMultiply: DstColor / Zero\nAdd: One / One\nSoft Add: OneMinusDstColor / One"); UnityEngine.Rendering.BlendMode blendSrc = (UnityEngine.Rendering.BlendMode)blendProps[0].floatValue; UnityEngine.Rendering.BlendMode blendDst = (UnityEngine.Rendering.BlendMode)blendProps[1].floatValue; EditorGUI.BeginChangeCheck(); float f = EditorGUIUtility.fieldWidth; float l = EditorGUIUtility.labelWidth; EditorGUIUtility.fieldWidth = 110f; EditorGUIUtility.labelWidth -= Mathf.Abs(f - EditorGUIUtility.fieldWidth); blendSrc = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Source Factor", blendSrc); blendDst = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Destination Factor", blendDst); EditorGUIUtility.fieldWidth = f; EditorGUIUtility.labelWidth = l; if (EditorGUI.EndChangeCheck()) { blendProps[0].floatValue = (float)blendSrc; blendProps[1].floatValue = (float)blendDst; } } } TCP2_GUI.Separator(); //-------------------------------------------------------------------------------------- if (EditorGUI.EndChangeCheck()) { PropertiesChanged(); } } //Update Keywords if (updateKeywords) { if (targets != null && targets.Length > 0) { foreach (Object t in targets) { (t as Material).shaderKeywords = keywordsList.ToArray(); EditorUtility.SetDirty(t); } } else { targetMaterial.shaderKeywords = keywordsList.ToArray(); EditorUtility.SetDirty(targetMaterial); } } #endif }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { FindProperties(properties); // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly this.materialEditor = materialEditor; Material material = materialEditor.target as Material; // Make sure that needed setup (ie keywords/renderqueue) are set up if we're switching some existing // material to a lightweight shader. if (firstTimeApply) { MaterialChanged(material); firstTimeApply = false; } #if SHOW_DEFAULT_INSPECTOR base.OnGUI(); return; #else //Header EditorGUILayout.BeginHorizontal(); string label = (Screen.width > 450f) ? "TOONY COLORS PRO 2 - INSPECTOR (Generated Shader)" : (Screen.width > 300f ? "TOONY COLORS PRO 2 - INSPECTOR" : "TOONY COLORS PRO 2"); TCP2_GUI.HeaderBig(label); if (TCP2_GUI.Button(TCP2_GUI.CogIcon, "O", "Open in Shader Generator")) { if (targetMaterial.shader != null) { TCP2_ShaderGenerator.OpenWithShader(targetMaterial.shader); } } EditorGUILayout.EndHorizontal(); TCP2_GUI.Separator(); //Iterate Shader properties // - Lightweight properties (Surface type, Blend mode) ShaderPropertiesGUI(material); // - Generated Shader/TCP2 properties materialEditor.serializedObject.Update(); SerializedProperty mShader = materialEditor.serializedObject.FindProperty("m_Shader"); toggledGroups.Clear(); if (materialEditor.isVisible && !mShader.hasMultipleDifferentValues && mShader.objectReferenceValue != null) { //Retina display fix EditorGUIUtility.labelWidth = TCP2_Utils.ScreenWidthRetina - 120f; EditorGUIUtility.fieldWidth = 64f; EditorGUI.BeginChangeCheck(); foreach (MaterialProperty p in properties) { bool visible = (toggledGroups.Count == 0 || toggledGroups.Peek()); //Hacky way to separate material inspector properties into foldout groups if (p.name.StartsWith("__BeginGroup")) { //Foldout if (visible) { GUILayout.Space(8f); p.floatValue = EditorGUILayout.Foldout(p.floatValue > 0, p.displayName, TCP2_GUI.FoldoutBold) ? 1 : 0; } EditorGUI.indentLevel++; toggledGroups.Push((p.floatValue > 0) && visible); } else if (p.name.StartsWith("__EndGroup")) { EditorGUI.indentLevel--; toggledGroups.Pop(); GUILayout.Space(8f); } else { //Draw regular property if (visible && (p.flags & (MaterialProperty.PropFlags.PerRendererData | MaterialProperty.PropFlags.HideInInspector)) == MaterialProperty.PropFlags.None) { this.materialEditor.ShaderProperty(p, p.displayName); } } } if (EditorGUI.EndChangeCheck()) { materialEditor.PropertiesChanged(); } } #endif // !SHOW_DEFAULT_INSPECTOR #if UNITY_5_5_OR_NEWER TCP2_GUI.Separator(); materialEditor.RenderQueueField(); #endif #if UNITY_5_6_OR_NEWER materialEditor.EnableInstancingField(); #endif }