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()); } } 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(true); ImageEx[] imageexs = _transform.GetComponentsInChildren(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(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(true); ImageEx[] imageexs = GetComponentsInChildren(true); Text[] texts = GetComponentsInChildren(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); } } } }