#if UNITY_EDITOR using System.Linq; using AllIn1VfxToolkit; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering; [CanEditMultipleObjects] public class AllIn1VfxCustomMaterialEditor : ShaderGUI { private Material targetMat; private UnityEngine.Rendering.BlendMode srcMode, dstMode; private UnityEngine.Rendering.CompareFunction zTestMode; private UnityEngine.Rendering.CullMode cullMode; private UnityEngine.Rendering.ColorWriteMask colorMask; private Material originalMaterialCopy; private MaterialEditor matEditor; private MaterialProperty[] matProperties; private uint[] materialDrawers = new uint[] { 1, 2, 4, 8, 16, 32 }; bool[] currEnabledDrawers; private const uint advancedConfigDrawer = 0; private const uint advancedShapeBlendDrawer = 1; private const uint mainShapeDrawer = 2; private const uint colorFxShapeDrawer = 3; private const uint alphaFxShapeDrawer = 4; private const uint uvFxShapeDrawer = 5; private enum RenderingPreset { Transparent, Additive, SoftAdditive, BlendAdd, Opaque, Custom } private RenderingPreset renderPreset; private string[] oldKeyWords; private GUIStyle propertiesStyle, bigLabel, smallLabel = new GUIStyle(), toggleButtonStyle, centeredTextStyle, smallTextStyle, smallBoldLabel; private const int bigFontSize = 16; private float tempValue; bool shape2On = false, shape3On = false, isPs = false; int effectCount = 1, shape1FirstProperty, shape2FirstProperty, shape3FirstProperty; public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { matEditor = materialEditor; matProperties = properties; targetMat = materialEditor.target as Material; oldKeyWords = targetMat.shaderKeywords; effectCount = 1; currEnabledDrawers = new bool[materialDrawers.Length]; uint iniDrawers = (uint)ShaderGUI.FindProperty("_EditorDrawers", matProperties).floatValue; for(int i = 0; i < materialDrawers.Length; i++) currEnabledDrawers[i] = (materialDrawers[i] & iniDrawers) > 0; propertiesStyle = new GUIStyle(EditorStyles.helpBox); propertiesStyle.margin = new RectOffset(0, 0, 0, 0); bigLabel = new GUIStyle(EditorStyles.boldLabel) { fontSize = bigFontSize }; smallLabel.fontStyle = FontStyle.Bold; toggleButtonStyle = new GUIStyle(GUI.skin.button) { alignment = TextAnchor.MiddleCenter, richText = true }; centeredTextStyle = new GUIStyle { alignment = TextAnchor.MiddleCenter, richText = true, fontSize = 13 }; smallTextStyle = new GUIStyle(GUI.skin.button) { fontSize = 10 }; smallBoldLabel = new GUIStyle(EditorStyles.boldLabel) { fontSize = 11 }; if(Selection.activeGameObject != null) isPs = Selection.activeGameObject.GetComponent() != null; GUILayout.Label("Configuration", bigLabel); GUILayout.Label("Presets:", smallBoldLabel); RenderingMode(); SetLabelAndFieldWidth(178, 75); currEnabledDrawers[advancedConfigDrawer] = GUILayout.Toggle(currEnabledDrawers[advancedConfigDrawer], new GUIContent("Show Advanced Configuration"), toggleButtonStyle); if(currEnabledDrawers[advancedConfigDrawer]) { EditorGUILayout.BeginVertical(propertiesStyle); Blending(); DrawLine(Color.grey, 1, 3); ZWrite(); DrawLine(Color.grey, 1, 3); ZTest(); DrawLine(Color.grey, 1, 3); Culling(); DrawLine(Color.grey, 1, 3); ColorMask(); DrawLine(Color.grey, 1, 3); DrawProperty(9); DrawLine(Color.grey, 1, 3); OneLineKeywordToggle("Use Unity Fog", "FOG_ON"); DrawLine(Color.grey, 1, 3); OneLineKeywordToggle("Use Custom Time", "TIMEISCUSTOM_ON"); DrawLine(Color.grey, 1, 3); EditorGUIUtility.labelWidth = 140; materialEditor.EnableInstancingField(); DrawLine(Color.grey, 1, 3); materialEditor.RenderQueueField(); EditorGUILayout.EndVertical(); } SectionSeparatorAndHeader("Shape Properties"); for(int i = 7; i <= 8; i++) DrawProperty(i); EditorGUILayout.Separator(); currEnabledDrawers[mainShapeDrawer] = GUILayout.Toggle(currEnabledDrawers[mainShapeDrawer], new GUIContent("Show Shape Configuration"), toggleButtonStyle); if(currEnabledDrawers[mainShapeDrawer]) { shape1FirstProperty = 11; shape2FirstProperty = 23; shape3FirstProperty = 35; ShapeProperties(1, shape1FirstProperty); EditorGUILayout.Separator(); ShapeProperties(2, shape2FirstProperty, true); EditorGUILayout.Separator(); if(shape2On) ShapeProperties(3, shape3FirstProperty, true); if(shape2On) ShapeResult(); } else { ShapeProperties(2, 23, true, true); if(shape2On) ShapeProperties(3, 35, true, true); } SectionSeparatorAndHeader("Color Effects"); currEnabledDrawers[colorFxShapeDrawer] = GUILayout.Toggle(currEnabledDrawers[colorFxShapeDrawer], new GUIContent("Show Color Effects"), toggleButtonStyle); if(currEnabledDrawers[colorFxShapeDrawer]) { Glow("Glow", "GLOW_ON"); ColorRamp("Color Ramp", "COLORRAMP_ON", "COLORRAMPGRAD_ON"); GenericEffect("Color Grading", "COLORGRADING_ON", 125, 128); GenericEffect("Hue Shift and Saturation", "HSV_ON", 71, 73); GenericEffect("Fresnel / Rim Color", "RIM_ON", 135, 141); GenericEffect("Intersection Glow", "DEPTHGLOW_ON", 64, 68); GenericEffect("Posterize", "POSTERIZE_ON", 149, 149); GenericEffect("Backface Tint", "BACKFACETINT_ON", 82, 83); FakeLightAndShadow("Fake Light And Shadow", "LIGHTANDSHADOW_ON", 144, 148); GenericEffect("Shape 1 Mask", "SHAPE1MASK_ON", 142, 143, true, new string[] { "It will only have a visual effect if shape 2 or 3 is enabled", "Use to avoid shape 1 from being affected by distortions and other shapes" }); ScreenDistort("Screen Distortion", "SCREENDISTORTION_ON", 103, 107); } SectionSeparatorAndHeader("Alpha Effects"); currEnabledDrawers[alphaFxShapeDrawer] = GUILayout.Toggle(currEnabledDrawers[alphaFxShapeDrawer], new GUIContent("Show Alpha Effects"), toggleButtonStyle); if(currEnabledDrawers[alphaFxShapeDrawer]) { GenericEffect("Alpha Mask", "MASK_ON", 69, 70, true); FadeDissolve("Fade From Noise Texture (Dissolve)", "FADE_ON", 115, 124); AlphaFade("Fade From Final Shape (Procedural Dissolve)", "ALPHAFADE_ON", 55, 57); GenericEffect("Soft Particles / Intersection Fade", "SOFTPART_ON", 47, 47, true); CameraDistFade("Camera Distance Fade", "CAMDISTFADE_ON", 129, 131); AlphaSmoothstep("Alpha Remap", "ALPHASMOOTHSTEP_ON", 53, 54); GenericEffect("Alpha Cutoff", "ALPHACUTOFF_ON", 52, 52, true, new string[] { "Use this to clip transparent pixels and reduce overdraw" }); } SectionSeparatorAndHeader("UV and Vertex Effects"); currEnabledDrawers[uvFxShapeDrawer] = GUILayout.Toggle(currEnabledDrawers[uvFxShapeDrawer], new GUIContent("Show UV Effects"), toggleButtonStyle); if(currEnabledDrawers[uvFxShapeDrawer]) { GenericEffect("Global Distortion", "DISTORT_ON", 78, 81); PolarUvs("Global Polar Coordinates", "POLARUV_ON"); if(isPs || oldKeyWords.Contains("SHAPEWEIGHTS_ON")) ShapeWeightVertexStream("Shape Weights Custom Stream", "SHAPEWEIGHTS_ON", 156); if(isPs || oldKeyWords.Contains("OFFSETSTREAM_ON")) OffsetVertexStream("Texture Offset Custom Stream", "OFFSETSTREAM_ON", 100); ShapeTextureOffset("Shape Texture Offset", "SHAPETEXOFFSET_ON", 74); GenericEffect("Global Texture Scroll", "TEXTURESCROLL_ON", 108, 109); GenericEffect("Twist", "TWISTUV_ON", 94, 97); GenericEffect("Wave", "WAVEUV_ON", 87, 91); GenericEffect("Round Wave", "ROUNDWAVEUV_ON", 92, 93); GenericEffect("Hand Drawn", "DOODLE_ON", 98, 99); GenericEffect("Pixelate", "PIXELATE_ON", 77, 77, true, new string[] { "Looks bad with distortion effects" }); TrailWidth("Trail Width", "TRAILWIDTH_ON", 58, 59); GenericEffect("Shake", "SHAKEUV_ON", 84, 86); GenericEffect("Vertex Offset", "VERTOFFSET_ON", 110, 114); } SetAndSaveEnabledDrawers(iniDrawers); } private void SetAndSaveEnabledDrawers(uint iniDrawers) { uint currDrawers = 0; for(int i = 0; i < currEnabledDrawers.Length; i++) { if(currEnabledDrawers[i]) currDrawers |= materialDrawers[i]; } if(iniDrawers != currDrawers) ShaderGUI.FindProperty("_EditorDrawers", matProperties).floatValue = currDrawers; } private void SectionSeparatorAndHeader(string headerText) { EditorGUILayout.Separator(); DrawLine(Color.grey, 1, 3); GUILayout.Label(headerText, bigLabel); } private void ShapeResult() { EditorGUILayout.Separator(); GUILayout.Label("Shape Result:", smallBoldLabel); currEnabledDrawers[advancedShapeBlendDrawer] = GUILayout.Toggle(currEnabledDrawers[advancedShapeBlendDrawer], new GUIContent("Show Shape Combination Options"), toggleButtonStyle); if(currEnabledDrawers[advancedShapeBlendDrawer]) { EditorGUILayout.BeginVertical(propertiesStyle); bool splitColor = DrawEffectSubKeywordToggle("Split Color And Alpha?", "SPLITRGBA_ON"); bool addResults = DrawEffectSubKeywordToggle("Add Shape Results?", "SHAPEADD_ON"); char operationChar = '*'; if(addResults) operationChar = '+'; if(splitColor) { GUILayout.Label("Color:", smallBoldLabel); DrawProperty(21); DrawProperty(33); if(shape3On) DrawProperty(45); GUILayout.Label("Alpha:", smallBoldLabel); DrawProperty(22); DrawProperty(34); if(shape3On) DrawProperty(46); EditorGUILayout.Separator(); GUILayout.Label("Final Shape Calculation:", smallBoldLabel); if(shape3On) { GUILayout.Label("RGB = ((Sh1.rgb * " + matProperties[21].floatValue + ") " + operationChar + " (Sh2.rgb * " + matProperties[33].floatValue + ")) " + operationChar + " (Sh3.rgb * " + matProperties[45].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); if(addResults) GUILayout.Label("A = max(max(Sh1.a * " + matProperties[22].floatValue + " , " + "Sh2.a * " + matProperties[34].floatValue + "), Sh3.a * " + matProperties[46].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); else GUILayout.Label("A = ((Sh1.a * " + matProperties[22].floatValue + ") " + operationChar + " (Sh2.a * " + matProperties[34].floatValue + ")) " + operationChar + " (Sh3.a * " + matProperties[46].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); } else { GUILayout.Label("RGB = (Sh1.rgb * " + matProperties[21].floatValue + ") " + operationChar + " (Sh2.rgb * " + matProperties[33].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); if(addResults) GUILayout.Label("A = max(Sh1.a * " + matProperties[22].floatValue + " , Sh2.a * " + matProperties[34].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); else GUILayout.Label("A = (Sh1.a * " + matProperties[22].floatValue + ") " + operationChar + " (Sh2.a * " + matProperties[34].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); } } else { GUILayout.Label("Shape weights:", smallBoldLabel); DrawProperty(21); DrawProperty(33); if(shape3On) DrawProperty(45); matProperties[22].floatValue = matProperties[21].floatValue; matProperties[34].floatValue = matProperties[33].floatValue; matProperties[46].floatValue = matProperties[45].floatValue; EditorGUILayout.Separator(); GUILayout.Label("Final Shape Calculation:", smallBoldLabel); if(shape3On) { if(!addResults) GUILayout.Label("Result = ((Shape1 * " + matProperties[21].floatValue + ") " + operationChar + " (Shape2 * " + matProperties[33].floatValue + ")) " + operationChar + " (Shape3 * " + matProperties[45].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); else { GUILayout.Label("RGB = ((Sh1.rgb * " + matProperties[21].floatValue + ") " + operationChar + " (Sh2.rgb * " + matProperties[33].floatValue + ")) " + operationChar + " (Sh3.rgb * " + matProperties[45].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); GUILayout.Label("A = max(max(Sh1.a * " + matProperties[22].floatValue + " , " + "Sh2.a * " + matProperties[34].floatValue + "), Sh3.a * " + matProperties[46].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); } } else { if(!addResults) GUILayout.Label("Result = (Shape1 * " + matProperties[21].floatValue + ") " + operationChar + " (Shape2 * " + matProperties[33].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); else { GUILayout.Label("RGB = (Sh1.rgb * " + matProperties[21].floatValue + ") " + operationChar + " (Sh2.rgb * " + matProperties[33].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); GUILayout.Label("A = max(Sh1.a * " + matProperties[22].floatValue + " , Sh2.a * " + matProperties[34].floatValue + ")", smallBoldLabel, GUILayout.Height(15)); } } } EditorGUILayout.EndVertical(); } } private void RenderingMode() { EditorGUILayout.BeginVertical(propertiesStyle); { MaterialProperty renderM = matProperties[0]; tempValue = renderM.floatValue; SetLabelAndFieldWidth(89, 75); renderPreset = (RenderingPreset)renderM.floatValue; if(renderPreset == RenderingPreset.Custom) renderPreset = (RenderingPreset)GUILayout.SelectionGrid((int)renderPreset, new string[] { "Transparent", "Additive", "Soft Add", "Blend Add / Premultiply", "Opaque", "Custom" }, 3, smallTextStyle); else renderPreset = (RenderingPreset)GUILayout.SelectionGrid((int)renderPreset, new string[] { "Transparent", "Additive", "Soft Add", "Blend Add / Premultiply", "Opaque" }, 3, smallTextStyle); renderM.floatValue = (float)(renderPreset); if(tempValue != renderM.floatValue && !Application.isPlaying) { switch(renderPreset) { case RenderingPreset.Transparent: targetMat.SetOverrideTag("RenderType", "Transparent"); targetMat.SetInt("_SrcMode", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); targetMat.SetInt("_DstMode", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); if(targetMat.renderQueue < 2050) targetMat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; targetMat.DisableKeyword("ADDITIVECONFIG_ON"); targetMat.DisableKeyword("PREMULTIPLYALPHA_ON"); targetMat.DisableKeyword("PREMULTIPLYCOLOR_ON"); break; case RenderingPreset.Additive: targetMat.SetOverrideTag("RenderType", "Transparent"); targetMat.SetInt("_SrcMode", (int)UnityEngine.Rendering.BlendMode.One); targetMat.SetInt("_DstMode", (int)UnityEngine.Rendering.BlendMode.One); if(targetMat.renderQueue < 2050) targetMat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; targetMat.EnableKeyword("ADDITIVECONFIG_ON"); targetMat.DisableKeyword("PREMULTIPLYALPHA_ON"); targetMat.DisableKeyword("PREMULTIPLYCOLOR_ON"); break; case RenderingPreset.SoftAdditive: targetMat.SetOverrideTag("RenderType", "Transparent"); targetMat.SetInt("_SrcMode", (int)UnityEngine.Rendering.BlendMode.OneMinusDstColor); targetMat.SetInt("_DstMode", (int)UnityEngine.Rendering.BlendMode.One); if(targetMat.renderQueue < 2050) targetMat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; targetMat.EnableKeyword("ADDITIVECONFIG_ON"); targetMat.DisableKeyword("PREMULTIPLYALPHA_ON"); targetMat.DisableKeyword("PREMULTIPLYCOLOR_ON"); break; case RenderingPreset.BlendAdd: targetMat.SetOverrideTag("RenderType", "Transparent"); targetMat.SetInt("_SrcMode", (int)UnityEngine.Rendering.BlendMode.One); targetMat.SetInt("_DstMode", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); if(targetMat.renderQueue < 2050) targetMat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent; targetMat.EnableKeyword("ADDITIVECONFIG_ON"); targetMat.DisableKeyword("PREMULTIPLYALPHA_ON"); targetMat.EnableKeyword("PREMULTIPLYCOLOR_ON"); break; case RenderingPreset.Opaque: targetMat.SetOverrideTag("RenderType", ""); targetMat.SetInt("_SrcMode", (int)UnityEngine.Rendering.BlendMode.One); targetMat.SetInt("_DstMode", (int)UnityEngine.Rendering.BlendMode.Zero); if(targetMat.renderQueue >= 2050) targetMat.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry; targetMat.SetInt("_ZWrite", 1); targetMat.DisableKeyword("ADDITIVECONFIG_ON"); targetMat.DisableKeyword("PREMULTIPLYALPHA_ON"); targetMat.DisableKeyword("PREMULTIPLYCOLOR_ON"); break; } Save(); oldKeyWords = targetMat.shaderKeywords; } } EditorGUILayout.EndVertical(); } private void Blending() { MaterialProperty srcM = matProperties[1]; MaterialProperty dstM = matProperties[2]; SetLabelAndFieldWidth(15, 15); EditorGUILayout.LabelField("Alpha Blending Modes:"); EditorGUILayout.BeginHorizontal(); { srcMode = (UnityEngine.Rendering.BlendMode)srcM.floatValue; dstMode = (UnityEngine.Rendering.BlendMode)dstM.floatValue; SetLabelAndFieldWidth(25, 50); tempValue = (float)(srcMode); srcMode = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Src", srcMode); if(tempValue != (float)(srcMode) && !Application.isPlaying) SaveAndSetCustomConfig(); EditorGUILayout.Space(); tempValue = (float)(dstMode); dstMode = (UnityEngine.Rendering.BlendMode)EditorGUILayout.EnumPopup("Dst", dstMode); if(tempValue != (float)(dstMode) && !Application.isPlaying) SaveAndSetCustomConfig(); srcM.floatValue = (float)(srcMode); dstM.floatValue = (float)(dstMode); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); SetLabelAndFieldWidth(137, 75); DrawEffectSubKeywordToggle("Additive configuration?", "ADDITIVECONFIG_ON", true); SetLabelAndFieldWidth(112, 75); DrawEffectSubKeywordToggle("Premultiply Alpha?", "PREMULTIPLYALPHA_ON", true); DrawEffectSubKeywordToggle("Premultiply Color?", "PREMULTIPLYCOLOR_ON", true); } private void ZWrite() { MaterialProperty zWrite = ShaderGUI.FindProperty("_ZWrite", matProperties); bool toggle = zWrite.floatValue > 0.9f ? true : false; EditorGUILayout.BeginHorizontal(); { SetLabelAndFieldWidth(89, 2); tempValue = zWrite.floatValue; toggle = GUILayout.Toggle(toggle, new GUIContent("Enable Z Write")); if(toggle) zWrite.floatValue = 1.0f; else zWrite.floatValue = 0.0f; if(tempValue != zWrite.floatValue && !Application.isPlaying) SaveAndSetCustomConfig(); } EditorGUILayout.EndHorizontal(); } private void ZTest() { MaterialProperty zTestM = ShaderGUI.FindProperty("_ZTestMode", matProperties); tempValue = zTestM.floatValue; SetLabelAndFieldWidth(72, 75); zTestMode = (UnityEngine.Rendering.CompareFunction)zTestM.floatValue; zTestMode = (UnityEngine.Rendering.CompareFunction)EditorGUILayout.EnumPopup("Z TestMode", zTestMode); zTestM.floatValue = (float)(zTestMode); if(tempValue != zTestM.floatValue && !Application.isPlaying) SaveAndSetCustomConfig(); } private void Culling() { MaterialProperty cullO = matProperties[3]; tempValue = cullO.floatValue; SetLabelAndFieldWidth(83, 35); cullMode = (UnityEngine.Rendering.CullMode)cullO.floatValue; cullMode = (UnityEngine.Rendering.CullMode)EditorGUILayout.EnumPopup("Culling Mode", cullMode); cullO.floatValue = (float)(cullMode); if(tempValue != cullO.floatValue && !Application.isPlaying) SaveAndSetCustomConfig(); } private void ColorMask() { MaterialProperty colorM = matProperties[6]; tempValue = colorM.floatValue; SetLabelAndFieldWidth(105, 35); colorMask = (UnityEngine.Rendering.ColorWriteMask)colorM.floatValue; colorMask = (UnityEngine.Rendering.ColorWriteMask)EditorGUILayout.EnumPopup("Color Write Mask", colorMask); colorM.floatValue = (float)(colorMask); if(tempValue != colorM.floatValue && !Application.isPlaying) SaveAndSetCustomConfig(); } private void OneLineKeywordToggle(string inspector, string keyword) { bool toggle = oldKeyWords.Contains(keyword); bool ini = toggle; SetLabelAndFieldWidth(87, 50); DrawEffectSubKeywordToggle(inspector, keyword, true); } private void ShapeProperties(int shapeNumber, int firstProperty, bool onlyIfKeyword = false, bool getIfEnabledAndReturn = false) { string shapeText = "Shape " + shapeNumber; string shapeKeyword = "SHAPE" + shapeNumber; bool toggle = false; if(shapeNumber == 2) shape2On = false; else if(shapeNumber == 3) shape3On = false; if(onlyIfKeyword) { bool ini = oldKeyWords.Contains(shapeKeyword + "_ON"); if(ini) { if(shapeNumber == 2) shape2On = true; else if(shapeNumber == 3) shape3On = true; } if(getIfEnabledAndReturn) return; toggle = ini; toggle = GUILayout.Toggle(toggle, new GUIContent("Use Shape " + shapeNumber + "?"), toggleButtonStyle); if(ini != toggle) { Save(); if(toggle) targetMat.EnableKeyword(shapeKeyword + "_ON"); else { targetMat.DisableKeyword(shapeKeyword + "_ON"); if(shapeNumber == 2) { targetMat.DisableKeyword("SHAPE3_ON"); targetMat.DisableKeyword("SHAPE2SCREENUV_ON"); targetMat.DisableKeyword("SHAPE3SCREENUV_ON"); AllIn1VfxWindow.SetShaderBasedOnEffectsAndPipeline(targetMat); } else if(shapeNumber == 3) { AllIn1VfxWindow.SetShaderBasedOnEffectsAndPipeline(targetMat); targetMat.DisableKeyword("SHAPE3SCREENUV_ON"); } } return; } } if(!onlyIfKeyword || toggle) { EditorGUILayout.BeginVertical(propertiesStyle); GUILayout.Label(shapeText + ":", smallBoldLabel); for(int i = firstProperty; i <= firstProperty + 3; i++) DrawProperty(i); string nextShapeKeyword = shapeKeyword + "CONTRAST_ON"; GenericEffect(shapeText + " Contrast", nextShapeKeyword, firstProperty + 4, firstProperty + 5, false); nextShapeKeyword = shapeKeyword + "DISTORT_ON"; GenericEffect(shapeText + " Distortion", nextShapeKeyword, firstProperty + 6, firstProperty + 9, false); nextShapeKeyword = shapeKeyword + "ROTATE_ON"; int shapeRotationPropertyIndex = 150 + (shapeNumber - 1) * 2; GenericEffect("Shape " + shapeNumber + " Rotation", nextShapeKeyword, shapeRotationPropertyIndex, shapeRotationPropertyIndex + 1, false); nextShapeKeyword = shapeKeyword + "SHAPECOLOR_ON"; GenericEffect("Shape " + shapeNumber + " RGB is Shape Color, Red Channel Is Alpha", nextShapeKeyword, -1, -1, false); nextShapeKeyword = shapeKeyword + "SCREENUV_ON"; int shapeSSUvScalePropertyIndex = 132 - 1 + shapeNumber; //- 1 from shader index to account for shape number GenericEffect("Shape " + shapeNumber + " Screen Position UVs?", nextShapeKeyword, shapeSSUvScalePropertyIndex, shapeSSUvScalePropertyIndex, false); nextShapeKeyword = "SHAPEDEBUG_ON"; int shapeDebugPropertyIndex = matProperties.Length - 1; bool ini = oldKeyWords.Contains(nextShapeKeyword) && matProperties[shapeDebugPropertyIndex].floatValue < shapeNumber + 0.5f && matProperties[shapeDebugPropertyIndex].floatValue > shapeNumber - 0.5f; bool toggle2 = ini; toggle2 = EditorGUILayout.BeginToggleGroup(shapeText + " Debug", toggle2); EditorGUILayout.EndToggleGroup(); if(ini != toggle2) { Save(); if(toggle2) targetMat.EnableKeyword(nextShapeKeyword); else targetMat.DisableKeyword(nextShapeKeyword); matProperties[shapeDebugPropertyIndex].floatValue = shapeNumber; } if(shapeNumber == 1) { EditorGUILayout.BeginHorizontal(); { if(oldKeyWords.Contains("SHAPE2_ON")) { if(GUILayout.Button("Copy Shape 2 Properties", GUILayout.Width(200))) { CopyShapePropertiesAndKeywords(shape1FirstProperty, shape2FirstProperty, 1, 2); } } if(oldKeyWords.Contains("SHAPE3_ON")) { if(GUILayout.Button("Copy Shape 3 Properties", GUILayout.Width(200))) { CopyShapePropertiesAndKeywords(shape1FirstProperty, shape3FirstProperty, 1, 3); } } } EditorGUILayout.EndHorizontal(); } else if(shapeNumber == 2) { EditorGUILayout.BeginHorizontal(); { if(GUILayout.Button("Copy Shape 1 Properties", GUILayout.Width(200))) { CopyShapePropertiesAndKeywords(shape2FirstProperty, shape1FirstProperty, 2, 1); } if(oldKeyWords.Contains("SHAPE3_ON")) { if(GUILayout.Button("Copy Shape 3 Properties", GUILayout.Width(200))) { CopyShapePropertiesAndKeywords(shape2FirstProperty, shape3FirstProperty, 2, 3); } } } EditorGUILayout.EndHorizontal(); } else if(shapeNumber == 3) { EditorGUILayout.BeginHorizontal(); { if(GUILayout.Button("Copy Shape 1 Properties", GUILayout.Width(200))) { CopyShapePropertiesAndKeywords(shape3FirstProperty, shape1FirstProperty, 3, 1); } if(GUILayout.Button("Copy Shape 2 Properties", GUILayout.Width(200))) { CopyShapePropertiesAndKeywords(shape3FirstProperty, shape2FirstProperty, 3, 2); } } EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); } } private void CopyShapePropertiesAndKeywords(int shapeToFirstProperty, int shapeFromFirstProperty, int shapeToNumber, int shapeFromNumber) { for(int i = 0; i < 12; i++) CopyShapeProperty(shapeToFirstProperty + i, shapeFromFirstProperty + i); CopyShapeProperty(129 + shapeToNumber, 129 + shapeFromNumber); if(oldKeyWords.Contains("SHAPE" + shapeFromNumber + "CONTRAST_ON")) targetMat.EnableKeyword("SHAPE" + shapeToNumber + "CONTRAST_ON"); else targetMat.DisableKeyword("SHAPE" + shapeToNumber + "CONTRAST_ON"); if(oldKeyWords.Contains("SHAPE" + shapeFromNumber + "DISTORT_ON")) targetMat.EnableKeyword("SHAPE" + shapeToNumber + "DISTORT_ON"); else targetMat.DisableKeyword("SHAPE" + shapeToNumber + "DISTORT_ON"); if(oldKeyWords.Contains("SHAPE" + shapeFromNumber + "ROTATE_ON")) targetMat.EnableKeyword("SHAPE" + shapeToNumber + "ROTATE_ON"); else targetMat.DisableKeyword("SHAPE" + shapeToNumber + "ROTATE_ON"); int rotationOffsetToIndex = 150 + ((shapeToNumber - 1) * 2); //150 is the first rotation property int rotationOffsetFromIndex = 150 + ((shapeFromNumber - 1) * 2); CopyShapeProperty(rotationOffsetToIndex, rotationOffsetFromIndex); CopyShapeProperty(rotationOffsetToIndex + 1, rotationOffsetFromIndex + 1); //Copy rotation speed if(oldKeyWords.Contains("SHAPE" + shapeFromNumber + "SHAPECOLOR_ON")) targetMat.EnableKeyword("SHAPE" + shapeToNumber + "SHAPECOLOR_ON"); else targetMat.DisableKeyword("SHAPE" + shapeToNumber + "SHAPECOLOR_ON"); if(oldKeyWords.Contains("SHAPE" + shapeFromNumber + "SCREENUV_ON")) targetMat.EnableKeyword("SHAPE" + shapeToNumber + "SCREENUV_ON"); else targetMat.DisableKeyword("SHAPE" + shapeToNumber + "SCREENUV_ON"); AllIn1VfxWindow.SetShaderBasedOnEffectsAndPipeline(targetMat); } private void CopyShapeProperty(int propertyTo, int propertyFrom) { if(matProperties[propertyTo].type == MaterialProperty.PropType.Float || matProperties[propertyTo].type == MaterialProperty.PropType.Range) { matProperties[propertyTo].floatValue = matProperties[propertyFrom].floatValue; } else if(matProperties[propertyTo].type == MaterialProperty.PropType.Vector) { matProperties[propertyTo].vectorValue = matProperties[propertyFrom].vectorValue; } else if(matProperties[propertyTo].type == MaterialProperty.PropType.Color) { matProperties[propertyTo].colorValue = matProperties[propertyFrom].colorValue; } else if(matProperties[propertyTo].type == MaterialProperty.PropType.Texture) { matProperties[propertyTo].textureValue = matProperties[propertyFrom].textureValue; matProperties[propertyTo].textureScaleAndOffset = matProperties[propertyFrom].textureScaleAndOffset; } } private void GenericEffect(string inspector, string keyword, int first, int last, bool effectCounter = true, string[] preMessages = null, int[] extraProperties = null, string[] keywordsToDisable = null) { bool toggle = oldKeyWords.Contains(keyword); bool ini = toggle; GUIContent effectNameLabel = new GUIContent(); effectNameLabel.tooltip = keyword + " (C#)"; if(effectCounter) { effectNameLabel.text = effectCount + "." + inspector; toggle = EditorGUILayout.BeginToggleGroup(effectNameLabel, toggle); effectCount++; } else { effectNameLabel.text = inspector; toggle = EditorGUILayout.BeginToggleGroup(effectNameLabel, toggle); } if(ini != toggle && !Application.isPlaying) { if(toggle) { targetMat.EnableKeyword(keyword); if(keywordsToDisable != null) foreach(string effect in keywordsToDisable) targetMat.DisableKeyword(effect); } else targetMat.DisableKeyword(keyword); AllIn1VfxWindow.SetShaderBasedOnEffectsAndPipeline(targetMat); Save(); } if(toggle && first > 0) { EditorGUILayout.BeginVertical(propertiesStyle); { if(preMessages != null) { foreach(string s in preMessages) { GUILayout.Label(s, smallLabel); EditorGUILayout.Space(); } } for(int i = first; i <= last; i++) DrawProperty(i); if(extraProperties != null) foreach(int i in extraProperties) DrawProperty(i); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void Glow(string inspector, string keyword) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { DrawProperty(62); EditorGUILayout.Separator(); if(DrawEffectSubKeywordToggle("Use Glow Mask Tex?", "GLOWTEX_ON")) DrawProperty(63); DrawProperty(60); DrawProperty(61); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void ColorRamp(string inspector, string keyword, string keyword2) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { bool useEditableGradient = false; if(AssetDatabase.Contains(targetMat)) { useEditableGradient = oldKeyWords.Contains(keyword2); bool gradientTex = useEditableGradient; gradientTex = GUILayout.Toggle(gradientTex, new GUIContent("Use Editable Gradient?")); if(useEditableGradient != gradientTex) { if(!Application.isPlaying) Save(); if(gradientTex) { useEditableGradient = true; targetMat.EnableKeyword(keyword2); } else targetMat.DisableKeyword(keyword2); } if(useEditableGradient) matEditor.ShaderProperty(matProperties[50], matProperties[50].displayName); } else { GUILayout.Label("*Save to folder to allow for dynamic Gradient property", smallLabel); EditorGUILayout.Space(); } GUILayout.Label("*Premultiply Color toggle recommended on additive setups", smallLabel); EditorGUILayout.Space(); if(!useEditableGradient) DrawProperty(48); DrawProperty(49); DrawProperty(51); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void AlphaSmoothstep(string inspector, string keyword, int first, int last) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { DrawMinMaxSlider("Min And Max Slider", first, last); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void CameraDistFade(string inspector, string keyword, int first, int last) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { DrawMinMaxSlider("Min And Max Slider", first, first + 1, 0f, 2000f); EditorGUILayout.Space(); DrawProperty(last); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void AlphaFade(string inspector, string keyword, int first, int last) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { DrawEffectSubKeywordToggle("Fade Amount Affects Global Transparency?", "ALPHAFADETRANSPARENCYTOO_ON"); if(isPs) { if(DrawEffectSubKeywordToggle("Fade Amount Driven By Vertex Stream? Custom1.y (See Docs)", "ALPHAFADEINPUTSTREAM_ON")) GUILayout.Label("*Custom Data Auto Setup button on Particle Helper\n component will do the setup for you", smallLabel); } DrawEffectSubKeywordToggle("Use grayscale as alpha? (Good for Additive configurations)", "ALPHAFADEUSEREDCHANNEL_ON"); if(DrawEffectSubKeywordToggle("Use Shape1 as fade mask?", "ALPHAFADEUSESHAPE1_ON")) { GUILayout.Label("*The effect is using the Shape1 result as the fade mask texture", smallLabel); } else GUILayout.Label("*The effect is using the global result as the fade mask texture", smallLabel); DrawLine(Color.grey, 1, 3); for(int i = first; i <= last; i++) DrawProperty(i); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void Blur(string inspector, string keyword, int first, int last) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { GUILayout.Label("It will only affect Shape 1", smallLabel); EditorGUILayout.Space(); DrawEffectSubKeywordToggle("Is Blur HD? (Performance Intensive)", "BLURISHD_ON"); for(int i = first; i <= last; i++) DrawProperty(i); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void OffsetVertexStream(string inspector, string keyword, int first) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { GUILayout.Label("*Use Particle System Custom Data Custom2.xy (See Docs)", smallLabel); EditorGUILayout.Space(); GUILayout.Label("*Custom Data Auto Setup button on Particle Helper\n component will do the setup for you", smallLabel); DrawProperty(first); if(shape2On) DrawProperty(first + 1); if(shape3On) DrawProperty(first + 2); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void ShapeWeightVertexStream(string inspector, string keyword, int first) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { if(!shape2On && !shape3On) { GUILayout.Label("*THIS EFFECT NEEDS AT LEAST 2 ACTIVE SHAPES", smallLabel); EditorGUILayout.Space(); EditorGUILayout.Space(); } GUILayout.Label("*Use Particle System Custom Data Custom2.z (See Docs)", smallLabel); EditorGUILayout.Space(); GUILayout.Label("*Custom Data Auto Setup button on Particle Helper\n component will do the setup for you", smallLabel); EditorGUILayout.Space(); GUILayout.Label("*Offset is added to shape weight", smallLabel); if(shape2On || shape3On) DrawProperty(first); if(shape2On) DrawProperty(first + 1); if(shape3On) DrawProperty(first + 2); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void ShapeTextureOffset(string inspector, string keyword, int first) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { GUILayout.Label("*Uses Random Seed to offset Shape textures", smallLabel); DrawProperty(first); if(shape2On) DrawProperty(first + 1); if(shape3On) DrawProperty(first + 2); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void ScreenDistort(string inspector, string keyword, int first, int last) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { GUILayout.Label("*This effect is performant intensive", smallLabel); GUILayout.Label("*Use the Transparent Preset", smallLabel); EditorGUILayout.Space(); DrawEffectSubKeywordToggle("Distort only objects behind? (Less performant)", "DISTORTONLYBACK_ON"); if(!DrawEffectSubKeywordToggle("Use Global Color as distortion mask?", "DISTORTUSECOL_ON")) { DrawProperty(first); for(int i = last - 1; i <= last; i++) DrawProperty(i); } for(int i = first + 1; i <= last - 2; i++) DrawProperty(i); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void FadeDissolve(string inspector, string keyword, int first, int last) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { DrawEffectSubKeywordToggle("Fade Amount Affects Global Transparency?", "ALPHAFADETRANSPARENCYTOO_ON"); if(isPs) { if(DrawEffectSubKeywordToggle("Fade Amount Driven By Vertex Stream? Custom1.y (See Docs)", "ALPHAFADEINPUTSTREAM_ON")) GUILayout.Label("*Custom Data Auto Setup button on Particle Helper\n component will do the setup for you", smallLabel); } DrawLine(Color.grey, 1, 3); for(int i = first; i <= first + 5; i++) DrawProperty(i); DrawLine(Color.grey, 1, 3); if(DrawEffectSubKeywordToggle("Use Fade Burn Color?", "FADEBURN_ON")) for(int i = first + 6; i <= last; i++) DrawProperty(i); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void PolarUvs(string inspector, string keyword) { if(SpecialCaseEffectBodyToggle(inspector, keyword, "POLARUVDISTORT_ON")) { EditorGUILayout.BeginVertical(propertiesStyle); { GUILayout.Label("*Disable Generate Mip Maps on textures \nto avoid transparent line visual artifact", smallLabel); EditorGUILayout.Space(); DrawEffectSubKeywordToggle("Polar Coords affects Distortion textures?", "POLARUVDISTORT_ON"); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void TrailWidth(string inspector, string keyword, int powerProperty, int gradientProperty) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { GUILayout.Label("Used for a more accurate width along trail (see Docs)", smallLabel); EditorGUILayout.Space(); GUILayout.Label("White is max width, black is 0 width", smallLabel); EditorGUILayout.Space(); DrawProperty(powerProperty); matEditor.ShaderProperty(matProperties[gradientProperty], matProperties[gradientProperty].displayName); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private void FakeLightAndShadow(string inspector, string keyword, int first, int last) { if(SpecialCaseEffectBodyToggle(inspector, keyword)) { EditorGUILayout.BeginVertical(propertiesStyle); { GUILayout.Label("You'll need AllIn1VfxFakeLightDirSetter.cs in the scene (see docs)", smallLabel); for(int i = first; i <= first + 2; i++) DrawProperty(i); DrawMinMaxSlider("Min And Max Slider", last - 1, last); } EditorGUILayout.EndVertical(); } EditorGUILayout.EndToggleGroup(); } private bool DrawEffectSubKeywordToggle(string inspector, string keyword, bool setCustomConfigAfter = false) { GUIContent propertyLabel = new GUIContent(); propertyLabel.text = inspector; propertyLabel.tooltip = keyword + " (C#)"; bool ini = oldKeyWords.Contains(keyword); bool toggle = ini; toggle = GUILayout.Toggle(toggle, propertyLabel); if(ini != toggle) { if(toggle) targetMat.EnableKeyword(keyword); else targetMat.DisableKeyword(keyword); AllIn1VfxWindow.SetShaderBasedOnEffectsAndPipeline(targetMat); if(!setCustomConfigAfter) Save(); else SaveAndSetCustomConfig(); } return toggle; } private bool SpecialCaseEffectBodyToggle(string inspector, string keyword, string extraKeywordToDisable = null) { bool toggle = oldKeyWords.Contains(keyword); bool ini = toggle; toggle = SpecialCaseEffectHeaderToggle(inspector, keyword, toggle); effectCount++; if(ini != toggle && !Application.isPlaying) { if(toggle) targetMat.EnableKeyword(keyword); else { targetMat.DisableKeyword(keyword); if(extraKeywordToDisable != null) targetMat.DisableKeyword(extraKeywordToDisable); } AllIn1VfxWindow.SetShaderBasedOnEffectsAndPipeline(targetMat); Save(); } return toggle; } private bool SpecialCaseEffectHeaderToggle(string inspector, string keyword, bool toggle) { GUIContent effectNameLabel = new GUIContent(); effectNameLabel.tooltip = keyword + " (C#)"; effectNameLabel.text = effectCount + "." + inspector; toggle = EditorGUILayout.BeginToggleGroup(effectNameLabel, toggle); return toggle; } private void DrawProperty(int index, bool noReset = false) { MaterialProperty targetProperty = matProperties[index]; EditorGUILayout.BeginHorizontal(); { GUIContent propertyLabel = new GUIContent(); propertyLabel.text = targetProperty.displayName; propertyLabel.tooltip = targetProperty.name + " (C#)"; matEditor.ShaderProperty(targetProperty, propertyLabel); if(!noReset) { GUIContent resetButtonLabel = new GUIContent(); resetButtonLabel.text = "R"; resetButtonLabel.tooltip = "Resets to default value"; if(GUILayout.Button(resetButtonLabel, GUILayout.Width(20))) ResetProperty(targetProperty); } } EditorGUILayout.EndHorizontal(); } private void ResetProperty(MaterialProperty targetProperty) { if(originalMaterialCopy == null) originalMaterialCopy = new Material(targetMat.shader); if(targetProperty.type == MaterialProperty.PropType.Float || targetProperty.type == MaterialProperty.PropType.Range) { targetProperty.floatValue = originalMaterialCopy.GetFloat(targetProperty.name); } else if(targetProperty.type == MaterialProperty.PropType.Vector) { targetProperty.vectorValue = originalMaterialCopy.GetVector(targetProperty.name); } else if(targetProperty.type == MaterialProperty.PropType.Color) { targetProperty.colorValue = originalMaterialCopy.GetColor(targetProperty.name); } else if(targetProperty.type == MaterialProperty.PropType.Texture) { targetProperty.textureValue = originalMaterialCopy.GetTexture(targetProperty.name); targetProperty.textureScaleAndOffset = new Vector4(1, 1, 0, 0); } } private void DrawMinMaxSlider(string sliderText, int propMin, int propMax, float valueMin = 0f, float valueMax = 1f) { DrawProperty(propMin); DrawProperty(propMax); MaterialProperty matPropMin = matProperties[propMin]; MaterialProperty matPropMax = matProperties[propMax]; float stepMin = matPropMin.floatValue; float stepMax = matPropMax.floatValue; EditorGUILayout.MinMaxSlider(sliderText, ref stepMin, ref stepMax, valueMin, valueMax); if(stepMax < stepMin) stepMax = stepMin; matPropMin.floatValue = stepMin; matPropMax.floatValue = stepMax; } private static void SetLabelAndFieldWidth(int labelWidth, int fieldWidth) { EditorGUIUtility.labelWidth = labelWidth; EditorGUIUtility.fieldWidth = fieldWidth; } //SetLabelWidthFromText("zTestMode"); //GUILayout.Label(EditorGUIUtility.labelWidth.ToString()); //SetFieldWidthFromText("Less Equals"); //GUILayout.Label(EditorGUIUtility.fieldWidth.ToString()); private void SetLabelWidthFromText(string text) { Vector2 textDimensions = GUI.skin.label.CalcSize(new GUIContent(text)); EditorGUIUtility.labelWidth = textDimensions.x; Debug.Log("Label: " + text + " " + textDimensions.x); } private void SetFieldWidthFromText(string text) { Vector2 textDimensions = GUI.skin.label.CalcSize(new GUIContent(text)); EditorGUIUtility.fieldWidth = textDimensions.x; Debug.Log("Field: " + text + " " + textDimensions.x); } private void DrawLine(Color color, int thickness = 2, int padding = 10) { Rect r = EditorGUILayout.GetControlRect(GUILayout.Height(padding + thickness)); r.height = thickness; r.y += (padding / 2f); r.x -= 2; r.width += 6; EditorGUI.DrawRect(r, color); } private void SaveAndSetCustomConfig() { renderPreset = RenderingPreset.Custom; MaterialProperty renderM = matProperties[0]; renderM.floatValue = (float)(renderPreset); Save(); } private void Save() { if(!Application.isPlaying) EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); EditorUtility.SetDirty(targetMat); } } #endif