| 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); | 
|             } | 
|         } | 
|     } | 
| } |