using UnityEngine; 
 | 
using UnityEngine.EventSystems; 
 | 
using UnityEngine.UI; 
 | 
  
 | 
[DisallowMultipleComponent] 
 | 
[ExecuteAlways] 
 | 
  
 | 
public class SmoothMask:UIBehaviour,ICanvasRaycastFilter { 
 | 
  
 | 
    [Range(0,1)] 
 | 
    [SerializeField] 
 | 
    private float m_Horizontal = 0f; 
 | 
    public float horizontal { get { return m_Horizontal; } } 
 | 
  
 | 
    [Range(0,1)] 
 | 
    [SerializeField] 
 | 
    private float m_Vertical = 0f; 
 | 
    public float vertical { get { return m_Vertical; } } 
 | 
  
 | 
    [SerializeField] 
 | 
    private Material[] m_ImageMaterials; 
 | 
    public Material[] imageMaterials { get { return m_ImageMaterials; } } 
 | 
  
 | 
    [SerializeField] 
 | 
    private Material[] m_TextMaterials; 
 | 
    public Material[] textMaterials { get { return m_TextMaterials; } } 
 | 
  
 | 
    [SerializeField] 
 | 
    private CanvasScaler m_CanvasScaler; 
 | 
    public CanvasScaler canvasScaler { 
 | 
        get { 
 | 
            return m_CanvasScaler ?? (m_CanvasScaler = GetComponentInParent<CanvasScaler>()); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public RectTransform rectTransform { 
 | 
        get { 
 | 
            return this.transform as RectTransform; 
 | 
        } 
 | 
    } 
 | 
    private Vector2 leftBottom; 
 | 
    private Vector2 rightTop; 
 | 
  
 | 
    public bool IsRaycastLocationValid(Vector2 sp,Camera eventCamera) { 
 | 
        return RectTransformUtility.RectangleContainsScreenPoint(rectTransform,sp,eventCamera); 
 | 
    } 
 | 
  
 | 
    void LateUpdate() { 
 | 
        UpdateChildMaterialSmoothMask(); 
 | 
    } 
 | 
  
 | 
    [ContextMenu("SetMaterial")] 
 | 
    public void UpdateChildrenMaterial() { 
 | 
        SetChildrenImageMaterial(this.transform); 
 | 
        SetChildrenTextMaterial(this.transform); 
 | 
    } 
 | 
  
 | 
    private void SetChildrenImageMaterial(Transform _transform) { 
 | 
        Image[] images = _transform.GetComponentsInChildren<Image>(true); 
 | 
        ImageEx[] imageexs = _transform.GetComponentsInChildren<ImageEx>(true); 
 | 
  
 | 
        if (null != images) 
 | 
        { 
 | 
            for(int i = 0;i < images.Length;i++) { 
 | 
                images[i].material = imageMaterials.Length > 0? imageMaterials[0] : null; 
 | 
            } 
 | 
        } 
 | 
  
 | 
        if (null!= imageexs) 
 | 
        { 
 | 
            for(int i = 0;i < imageexs.Length;i++) { 
 | 
                imageexs[i].material = imageMaterials.Length > 0? imageMaterials[0] : null; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private void SetChildrenTextMaterial(Transform _parent) { 
 | 
        Text[] texts = _parent.GetComponentsInChildren<Text>(true); 
 | 
        if(texts!= null) { 
 | 
            for(int i = 0;i < texts.Length;i++) { 
 | 
                texts[i].material = textMaterials.Length > 0? textMaterials[0] : null; 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
    private void UpdateChildMaterialSmoothMask() { 
 | 
        var scaleX = canvasScaler.transform.localScale.x; 
 | 
        var scaleY = canvasScaler.transform.localScale.y; 
 | 
  
 | 
        Vector3[] corners = new Vector3[4]; 
 | 
        rectTransform.GetWorldCorners(corners); 
 | 
  
 | 
        leftBottom = new Vector2(corners[0].x, corners[0].y); 
 | 
        rightTop = new Vector2(corners[2].x, corners[2].y); 
 | 
  
 | 
        if(imageMaterials != null) { 
 | 
            for(int i = 0;i < imageMaterials.Length;i++) { 
 | 
                SetSmoothMask(imageMaterials[i],leftBottom,rightTop,new Vector2(horizontal,vertical)); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        if(textMaterials != null) { 
 | 
            for(int i = 0;i < textMaterials.Length;i++) { 
 | 
                SetSmoothMask(textMaterials[i],leftBottom,rightTop,new Vector2(horizontal,vertical)); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
#if UNITY_EDITOR 
 | 
    void OnDrawGizmos() { 
 | 
        Vector3[] corners = new Vector3[4]; 
 | 
        rectTransform.GetWorldCorners(corners); 
 | 
         
 | 
        Gizmos.color = Color.red; // 设置线框颜色 
 | 
        // 绘制矩形边界 
 | 
        Gizmos.DrawLine(corners[0], corners[1]); // 左下→左上 
 | 
        Gizmos.DrawLine(corners[1], corners[2]); // 左上→右上 
 | 
        Gizmos.DrawLine(corners[2], corners[3]); // 右上→右下 
 | 
        Gizmos.DrawLine(corners[3], corners[0]); // 右下→左下 
 | 
    } 
 | 
#endif 
 | 
  
 | 
    void SetSmoothMask(Material material,Vector2 leftBottom,Vector2 rightTop,Vector2 smoothRect) { 
 | 
  
 | 
        Image[] images = GetComponentsInChildren<Image>(true); 
 | 
        ImageEx[] imageexs = GetComponentsInChildren<ImageEx>(true); 
 | 
        Text[] texts = GetComponentsInChildren<Text>(true); 
 | 
  
 | 
        if (null != images) 
 | 
        { 
 | 
            foreach (var graphic in images) 
 | 
            { 
 | 
                graphic.material.SetVector("_LeftBottom",leftBottom); 
 | 
                graphic.material.SetVector("_RightTop",rightTop); 
 | 
                graphic.material.SetVector("_SmoothRect",smoothRect); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        if (null != imageexs) 
 | 
        { 
 | 
            foreach (var graphic in imageexs) 
 | 
            { 
 | 
                graphic.material.SetVector("_LeftBottom",leftBottom); 
 | 
                graphic.material.SetVector("_RightTop",rightTop); 
 | 
                graphic.material.SetVector("_SmoothRect",smoothRect); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        if (null != texts) 
 | 
        { 
 | 
            foreach (var graphic in texts) 
 | 
            { 
 | 
                graphic.material.SetVector("_LeftBottom",leftBottom); 
 | 
                graphic.material.SetVector("_RightTop",rightTop); 
 | 
                graphic.material.SetVector("_SmoothRect",smoothRect); 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
} 
 |