330 lines
11 KiB
C#
330 lines
11 KiB
C#
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<Mask>().Length > 1)
|
|
// {
|
|
// GUILayout.Label("More than one instance of Mask attached.\nPlease only use one.");
|
|
// return;
|
|
// }
|
|
//
|
|
// if ((maskTarget.GetComponent<MeshRenderer>() != null) &&
|
|
// (maskTarget.GetComponent<MeshFilter>() != null) &&
|
|
// (maskTarget.GetComponent<Renderer>().sharedMaterial != null) &&
|
|
// (maskTarget.GetComponent<Renderer>().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<Renderer>().enabled);
|
|
// if (displayMask != maskTarget.GetComponent<Renderer>().enabled)
|
|
// {
|
|
// maskTarget.GetComponent<Renderer>().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<Renderer>().sharedMaterial.mainTexture;
|
|
|
|
List<Component> components = new List<Component>();
|
|
components.AddRange(maskTarget.transform.parent.gameObject.GetComponentsInChildren<Renderer>());
|
|
components.AddRange(maskTarget.transform.parent.gameObject.GetComponentsInChildren<Graphic>());
|
|
List<Material> differentOriginalMaterials = new List<Material>();
|
|
List<Material> differentNewMaterials = new List<Material>();
|
|
|
|
List<Material> differentReusableMaterials = GetAllReusableMaterials(components, maskedSpriteWorldCoordsShader, maskedUnlitWorldCoordsShader);// new List<Material>();
|
|
|
|
foreach (Component component in components)
|
|
{
|
|
if (component.gameObject != maskTarget.gameObject)
|
|
{
|
|
List<Material> currSharedMaterials = new List<Material>();
|
|
List<bool> areCurrSharedMaterialsTexts = new List<bool>();
|
|
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<Material> 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<Material> GetAllReusableMaterials(List<Component> components, Shader maskedSpriteWorldCoordsShader, Shader maskedUnlitWorldCoordsShader)
|
|
{
|
|
List<Material> differentReusableMaterials = new List<Material>();
|
|
Mask maskTarget = (Mask)target;
|
|
|
|
foreach (Component component in components)
|
|
{
|
|
if (component.gameObject != maskTarget.gameObject)
|
|
{
|
|
List<Material> currSharedMaterials = new List<Material>();
|
|
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;
|
|
}
|
|
}
|
|
} |