using UnityEngine; using UnityEditor; using System.Collections.Generic; using UnityEngine.UI; namespace ToJ { [CustomEditor(typeof(Mask))] public class MaskEditor : Editor { // public override void OnInspectorGUI() // { // Mask maskTarget = (Mask)target; // // if (maskTarget.GetComponents().Length > 1) // { // GUILayout.Label("More than one instance of Mask attached.\nPlease only use one."); // return; // } // // if ((maskTarget.GetComponent() != null) && // (maskTarget.GetComponent() != null) && // (maskTarget.GetComponent().sharedMaterial != null) && // (maskTarget.GetComponent().sharedMaterial.mainTexture != null)) // { // // //maskTarget.maskMappingWorldAxis = (Mask.MappingAxis)EditorGUILayout.EnumPopup("Mask Mapping World Axis", maskTarget.maskMappingWorldAxis); // // Mask.MappingAxis maskMappingWorldAxis = (Mask.MappingAxis)EditorGUILayout.EnumPopup("Mask Mapping World Axis", maskTarget.maskMappingWorldAxis); // if (maskMappingWorldAxis != maskTarget.maskMappingWorldAxis) // { // maskTarget.maskMappingWorldAxis = maskMappingWorldAxis; // } // // // bool invertAxis = EditorGUILayout.Toggle("Invert Axis", maskTarget.invertAxis); // if (invertAxis != maskTarget.invertAxis) // { // maskTarget.invertAxis = invertAxis; // } // // bool clampAlphaHorizontally = EditorGUILayout.Toggle("Clamp Alpha Horizontally", maskTarget.clampAlphaHorizontally); // if (clampAlphaHorizontally != maskTarget.clampAlphaHorizontally) // { // maskTarget.clampAlphaHorizontally = clampAlphaHorizontally; // } // // bool clampAlphaVertically = EditorGUILayout.Toggle("Clamp Alpha Vertically", maskTarget.clampAlphaVertically); // if (clampAlphaVertically != maskTarget.clampAlphaVertically) // { // maskTarget.clampAlphaVertically = clampAlphaVertically; // } // // float clampingBorder = EditorGUILayout.FloatField("Clamping Border", maskTarget.clampingBorder); // if (clampingBorder != maskTarget.clampingBorder) // { // maskTarget.clampingBorder = clampingBorder; // } // // bool useMaskAlphaChannel = EditorGUILayout.Toggle("Use Mask Alpha Channel (not RGB)", maskTarget.useMaskAlphaChannel); // if (useMaskAlphaChannel != maskTarget.useMaskAlphaChannel) // { // maskTarget.useMaskAlphaChannel = useMaskAlphaChannel; // } // // // if (!Application.isPlaying) // { // bool displayMask = EditorGUILayout.Toggle("Display Mask", maskTarget.GetComponent().enabled); // if (displayMask != maskTarget.GetComponent().enabled) // { // maskTarget.GetComponent().enabled = displayMask; // } // // } // // if (!Application.isPlaying) // { // if (GUILayout.Button("Apply Mask to Siblings in Hierarchy")) // { // ApplyMaskToChildren(); // } // } // // } // else // { // GUILayout.Label("Please attach MeshFilter and MeshRenderer.\nAlso assign a texture to MeshRenderer."); // } // // if (GUI.changed) // { // EditorUtility.SetDirty(target); // } // } private void ApplyMaskToChildren() { Mask maskTarget = (Mask)target; Shader maskedSpriteWorldCoordsShader = Shader.Find("Alpha Masked/Sprites Alpha Masked - World Coords"); Shader maskedUnlitWorldCoordsShader = Shader.Find("Alpha Masked/Unlit Alpha Masked - World Coords"); Shader spriteDefaultShader = Shader.Find("Sprites/Default"); Shader unlitTransparentShader = Shader.Find("Unlit/Transparent"); Shader UIDefaultShader = Shader.Find("UI/Default"); Shader UIDefaultFontShader = Shader.Find("UI/Default Font"); if ((maskedSpriteWorldCoordsShader == null) || (maskedUnlitWorldCoordsShader == null)) { Debug.Log("Shaders necessary for masking don't seem to be present in the project."); return; } Texture maskTexture = maskTarget.GetComponent().sharedMaterial.mainTexture; List components = new List(); components.AddRange(maskTarget.transform.parent.gameObject.GetComponentsInChildren()); components.AddRange(maskTarget.transform.parent.gameObject.GetComponentsInChildren()); List differentOriginalMaterials = new List(); List differentNewMaterials = new List(); List differentReusableMaterials = GetAllReusableMaterials(components, maskedSpriteWorldCoordsShader, maskedUnlitWorldCoordsShader);// new List(); foreach (Component component in components) { if (component.gameObject != maskTarget.gameObject) { List currSharedMaterials = new List(); List areCurrSharedMaterialsTexts = new List(); if (component is Renderer) { currSharedMaterials.AddRange(((Renderer)component).sharedMaterials); for (int i = 0; i < ((Renderer)component).sharedMaterials.Length; i++) { areCurrSharedMaterialsTexts.Add(false); } } else if (component is Graphic) { currSharedMaterials.Add(((Graphic)component).material); areCurrSharedMaterialsTexts.Add(component is Text); } bool materialsChanged = false; for (int i = 0; i < currSharedMaterials.Count; i++) { Material material = currSharedMaterials[i]; if (!differentOriginalMaterials.Contains(material)) { Material materialToBeUsed = null; if ((material.shader == spriteDefaultShader) || (material.shader == unlitTransparentShader) || (material.shader == UIDefaultShader) || (material.shader == UIDefaultFontShader)) { Material reusableMaterial = FindSuitableMaskedMaterial(material, differentReusableMaterials, maskedSpriteWorldCoordsShader, maskedUnlitWorldCoordsShader, spriteDefaultShader, unlitTransparentShader, UIDefaultShader, UIDefaultFontShader); if (reusableMaterial == null) { differentOriginalMaterials.Add(material); Material newMaterial = new Material(material); if (material.shader == spriteDefaultShader) { newMaterial.shader = maskedSpriteWorldCoordsShader; } else if (material.shader == unlitTransparentShader) { newMaterial.shader = maskedUnlitWorldCoordsShader; } else if (material.shader == UIDefaultShader) { newMaterial.shader = maskedSpriteWorldCoordsShader; } else if (material.shader == UIDefaultFontShader) { newMaterial.shader = maskedSpriteWorldCoordsShader; } if (areCurrSharedMaterialsTexts[i] == true) { newMaterial.SetFloat("_IsThisText", 1); } newMaterial.name = material.name + " Masked"; newMaterial.SetTexture("_AlphaTex", maskTexture); materialToBeUsed = newMaterial; differentNewMaterials.Add(newMaterial); currSharedMaterials[i] = newMaterial; materialsChanged = true; } else { currSharedMaterials[i] = reusableMaterial; materialsChanged = true; reusableMaterial.SetTexture("_AlphaTex", maskTexture); materialToBeUsed = reusableMaterial; } } else if ((material.shader == maskedSpriteWorldCoordsShader) || (material.shader == maskedUnlitWorldCoordsShader)) { if (material.GetTexture("_AlphaTex") != maskTexture) { material.SetTexture("_AlphaTex", maskTexture); } if (areCurrSharedMaterialsTexts[i] == true) { material.SetFloat("_IsThisText", 1); } materialToBeUsed = material; } if (materialToBeUsed != null) { maskTarget.SetMaskMappingAxisInMaterial(maskTarget.maskMappingWorldAxis, materialToBeUsed); maskTarget.SetMaskBoolValueInMaterial("_ClampHoriz", maskTarget.clampAlphaHorizontally, materialToBeUsed); maskTarget.SetMaskBoolValueInMaterial("_ClampVert", maskTarget.clampAlphaVertically, materialToBeUsed); maskTarget.SetMaskBoolValueInMaterial("_UseAlphaChannel", maskTarget.useMaskAlphaChannel, materialToBeUsed); } } else { int index = differentOriginalMaterials.IndexOf(material); currSharedMaterials[i] = differentNewMaterials[index]; materialsChanged = true; } } if (materialsChanged == true) { if (component is Renderer) { ((Renderer)component).sharedMaterials = currSharedMaterials.ToArray(); } else if (component is Graphic) { ((Graphic)component).material = currSharedMaterials[0]; } } } } Debug.Log("Mask applied."); } private Material FindSuitableMaskedMaterial(Material nonMaskedMaterial, List differentReusableMaterials, Shader maskedSpriteWorldCoordsShader, Shader maskedUnlitWorldCoordsShader, Shader spriteDefaultShader, Shader unlitTransparentShader, Shader UIDefaultShader, Shader UIDefaultFontShader) { foreach (Material material in differentReusableMaterials) { if ((nonMaskedMaterial.shader == spriteDefaultShader) && (material.shader == maskedSpriteWorldCoordsShader)) { if ((material.name == nonMaskedMaterial.name + " Masked") && (material.GetColor("_Color") == nonMaskedMaterial.GetColor("_Color")) && (material.GetFloat("PixelSnap") == nonMaskedMaterial.GetFloat("PixelSnap"))) { return material; } } else if ((nonMaskedMaterial.shader == unlitTransparentShader) && (material.shader == maskedUnlitWorldCoordsShader)) { if ((material.name == nonMaskedMaterial.name + " Masked") && (material.mainTexture == nonMaskedMaterial.mainTexture)) { return material; } } else if ((nonMaskedMaterial.shader == UIDefaultFontShader) && (material.shader == maskedSpriteWorldCoordsShader)) { if ((material.name == nonMaskedMaterial.name + " Masked") && (material.GetColor("_Color") == nonMaskedMaterial.GetColor("_Color"))) { return material; } } } return null; } private List GetAllReusableMaterials(List components, Shader maskedSpriteWorldCoordsShader, Shader maskedUnlitWorldCoordsShader) { List differentReusableMaterials = new List(); Mask maskTarget = (Mask)target; foreach (Component component in components) { if (component.gameObject != maskTarget.gameObject) { List currSharedMaterials = new List(); if (component is Renderer) { currSharedMaterials.AddRange(((Renderer)component).sharedMaterials); } else if (component is Graphic) { currSharedMaterials.Add(((Graphic)component).material); } //Material[] currSharedMaterials = renderer.sharedMaterials; for (int i = 0; i < currSharedMaterials.Count; i++) { Material material = currSharedMaterials[i]; if ((material.shader == maskedSpriteWorldCoordsShader) || (material.shader == maskedUnlitWorldCoordsShader)) { differentReusableMaterials.Add(material); } } } } return differentReusableMaterials; } } }