| using System.Collections.Generic; | 
| using UnityEngine; | 
| using UnityEngine.Sprites; | 
| using UnityEngine.UI; | 
|   | 
| [DisallowMultipleComponent] | 
| [AddComponentMenu("UI/Custom/Circle Image")] | 
| [RequireComponent(typeof(Image))] | 
| public class RoundedRectangleImage:BaseMeshEffect,ICanvasRaycastFilter { | 
|   | 
|     [SerializeField] | 
|     float m_Radius = 10f; | 
|     public float radius { get { return m_Radius; } } | 
|   | 
|     [SerializeField] | 
|     [Range(16,128)] | 
|     int m_Segements = 16; | 
|     public int segements { get { return m_Segements; } } | 
|   | 
|     [SerializeField] | 
|     Vector2 m_RealArea = Vector2.one * 100; | 
|     public Vector2 realArea { get { return m_RealArea; } } | 
|   | 
|     private Image m_Image; | 
|     public Image image { get { return m_Image ?? (m_Image = this.AddMissingComponent<Image>()); } } | 
|   | 
|     List<Vector3> vertexPosition = new List<Vector3>(); | 
|     public override void ModifyMesh(VertexHelper vh) { | 
|         vh.Clear(); | 
|         vertexPosition.Clear(); | 
|   | 
|         var tw = image.rectTransform.rect.width; | 
|         var th = image.rectTransform.rect.height; | 
|         var uv = image.overrideSprite != null ? DataUtility.GetOuterUV(image.overrideSprite) : Vector4.zero; | 
|   | 
|         var uvCenterX = (uv.x + uv.z) * 0.5f; | 
|         var uvCenterY = (uv.y + uv.w) * 0.5f; | 
|         var uvScaleX = (uv.z - uv.x) / tw; | 
|         var uvScaleY = (uv.w - uv.y) / th; | 
|   | 
|         var interval = radius / (segements - 1); | 
|   | 
|         var center = new Vector2(realArea.x * 0.5f - radius,realArea.y * 0.5f - radius); | 
|         for(int i = 0;i < segements;i++) { | 
|             var position = new Vector2(); | 
|             var offsetX = interval * i; | 
|             position.x = center.x + offsetX; | 
|             position.y = center.y + Mathf.Sqrt(radius * radius - offsetX * offsetX); | 
|             vertexPosition.Add(position); | 
|             var vertex = new UIVertex(); | 
|             vertex.position = position; | 
|             vertex.color = image.color; | 
|             vertex.uv0 = new Vector2(position.x * uvScaleX + uvCenterX,position.y * uvScaleY + uvCenterY); | 
|             vh.AddVert(vertex); | 
|         } | 
|   | 
|         center = new Vector2(realArea.x * 0.5f - radius,-realArea.y * 0.5f + radius); | 
|         for(int i = 0;i < segements;i++) { | 
|             var position = new Vector2(); | 
|             var offsetX = interval * i; | 
|             position.x = center.x + radius - offsetX; | 
|             position.y = center.y - Mathf.Sqrt(radius * radius - (radius - offsetX) * (radius - offsetX)); | 
|             vertexPosition.Add(position); | 
|             var vertex = new UIVertex(); | 
|             vertex.position = position; | 
|             vertex.color = image.color; | 
|             vertex.uv0 = new Vector2(position.x * uvScaleX + uvCenterX,position.y * uvScaleY + uvCenterY); | 
|             vh.AddVert(vertex); | 
|         } | 
|   | 
|         center = new Vector2(-realArea.x * 0.5f + radius,-realArea.y * 0.5f + radius); | 
|         for(int i = 0;i < segements;i++) { | 
|             var position = new Vector2(); | 
|             var offsetX = interval * i; | 
|             position.x = center.x - offsetX; | 
|             position.y = center.y - Mathf.Sqrt(radius * radius - offsetX * offsetX); | 
|             vertexPosition.Add(position); | 
|             var vertex = new UIVertex(); | 
|             vertex.position = position; | 
|             vertex.color = image.color; | 
|             vertex.uv0 = new Vector2(position.x * uvScaleX + uvCenterX,position.y * uvScaleY + uvCenterY); | 
|             vh.AddVert(vertex); | 
|         } | 
|   | 
|         center = new Vector2(-realArea.x * 0.5f + radius,realArea.y * 0.5f - radius); | 
|         for(int i = 0;i < segements;i++) { | 
|             var position = new Vector2(); | 
|             var offsetX = interval * i; | 
|             position.x = center.x - radius + offsetX; | 
|             position.y = center.y + Mathf.Sqrt(radius * radius - (radius - offsetX) * (radius - offsetX)); | 
|             vertexPosition.Add(position); | 
|             var vertex = new UIVertex(); | 
|             vertex.position = position; | 
|             vertex.color = image.color; | 
|             vertex.uv0 = new Vector2(position.x * uvScaleX + uvCenterX,position.y * uvScaleY + uvCenterY); | 
|             vh.AddVert(vertex); | 
|         } | 
|   | 
|         var triangleCount = segements * 12 - 3; | 
|         for(int i = 0,vIdx = 1;i < triangleCount - 3;i += 3,vIdx++) { | 
|             vh.AddTriangle(vIdx,0,vIdx + 1); | 
|         } | 
|     } | 
|   | 
|     public virtual bool IsRaycastLocationValid(Vector2 screenPoint,Camera eventCamera) { | 
|         var sprite = image.overrideSprite; | 
|         if(sprite == null) { | 
|             return true; | 
|         } | 
|   | 
|         Vector2 local; | 
|         RectTransformUtility.ScreenPointToLocalPointInRectangle(image.rectTransform,screenPoint,eventCamera,out local); | 
|         return Contains(local,vertexPosition); | 
|     } | 
|   | 
|     private bool Contains(Vector2 _p,List<Vector3> _vertexPositions) { | 
|         var crossNumber = 0; | 
|         crossNumber += UIUtility.RayCrossingCount(_p,_vertexPositions); | 
|         return (crossNumber & 1) == 1; | 
|     } | 
|   | 
| } |