| using System.Collections; | 
| using System.Collections.Generic; | 
| using UnityEngine; | 
| using UnityEngine.UI; | 
| using UnityEngine.Sprites; | 
|   | 
| [AddComponentMenu("UI/Custom/SquareHollow Image")] | 
| [DisallowMultipleComponent] | 
| [RequireComponent(typeof(Image))] | 
| public class SquareHollowImage : BaseMeshEffect, ICanvasRaycastFilter | 
| { | 
|     [SerializeField] | 
|     Vector2 m_Center; | 
|     public Vector2 center { | 
|         get { return m_Center; } | 
|         set { | 
|             m_Center = value; | 
|             base.graphic.SetVerticesDirty(); | 
|         } | 
|     } | 
|   | 
|     [SerializeField] | 
|     Vector2 m_Cell; | 
|     public Vector2 cell { | 
|         get { | 
|             return m_Cell; | 
|         } | 
|         set { | 
|             m_Cell = value; | 
|             base.graphic.SetVerticesDirty(); | 
|         } | 
|     } | 
|   | 
|     public RectTransform rectTransform { get { return this.transform as RectTransform; } } | 
|   | 
|     private List<Vector3> innerVertices = new List<Vector3>(); | 
|     private List<Vector3> outterVertices = new List<Vector3>(); | 
|   | 
|     private Image m_Image; | 
|     public Image image { get { return m_Image ?? (m_Image = this.AddMissingComponent<Image>()); } } | 
|   | 
|     public override void ModifyMesh(VertexHelper vh) | 
|     { | 
|         vh.Clear(); | 
|         innerVertices.Clear(); | 
|         outterVertices.Clear(); | 
|   | 
|         var width = image.rectTransform.rect.width; | 
|         var height = image.rectTransform.rect.height; | 
|         var outerArea = new Vector2(0.5f * width, 0.5f * height); | 
|   | 
|         var leftBottom = new Vector2(outerArea.x * -1f, outerArea.y * -1f); | 
|         var innerArea = new Vector2(Mathf.Clamp(cell.x, 0, width), Mathf.Clamp(cell.y, 0, height)); | 
|         var innerCenter = new Vector2(Mathf.Clamp(center.x, (innerArea.x - width) * 0.5f, (width - innerArea.x) * 0.5f), Mathf.Clamp(center.y, (innerArea.y - height) * 0.5f, (height - innerArea.y) * 0.5f)); | 
|   | 
|         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) / width; | 
|         var uvScaleY = (uv.w - uv.y) / height; | 
|   | 
|         var positions = new List<Vector3>(); | 
|         var position = Vector3.zero; | 
|         position = new Vector3(innerCenter.x + innerArea.x * -0.5f, innerCenter.y + innerArea.y * -0.5f); | 
|         positions.Add(position); | 
|         innerVertices.Add(position); | 
|   | 
|         position = new Vector3(outerArea.x * -1f, outerArea.y * -1f); | 
|         positions.Add(position); | 
|         outterVertices.Add(position); | 
|   | 
|         position = new Vector3(innerCenter.x + innerArea.x * 0.5f, innerCenter.y + innerArea.y * -0.5f); | 
|         positions.Add(position); | 
|         innerVertices.Add(position); | 
|   | 
|         position = new Vector3(outerArea.x * 1f, outerArea.y * -1f); | 
|         positions.Add(position); | 
|         outterVertices.Add(position); | 
|   | 
|         position = new Vector3(innerCenter.x + innerArea.x * 0.5f, innerCenter.y + innerArea.y * 0.5f); | 
|         positions.Add(position); | 
|         innerVertices.Add(position); | 
|   | 
|         position = new Vector3(outerArea.x * 1f, outerArea.y * 1f); | 
|         positions.Add(position); | 
|         outterVertices.Add(position); | 
|   | 
|         position = new Vector3(innerCenter.x + innerArea.x * -0.5f, innerCenter.y + innerArea.y * 0.5f); | 
|         positions.Add(position); | 
|         innerVertices.Add(position); | 
|   | 
|         position = new Vector3(outerArea.x * -1f, outerArea.y * 1f); | 
|         positions.Add(position); | 
|         outterVertices.Add(position); | 
|   | 
|         for (int i = 0; i < positions.Count; i++) | 
|         { | 
|             position = positions[i]; | 
|             var uv0 = new Vector2(position.x * uvScaleX + uvCenterX, position.y * uvScaleY + uvCenterY); | 
|             var uiVertex = UIUtility.PackageUIVertex(position, uv0, image.color); | 
|             vh.AddVert(uiVertex); | 
|         } | 
|   | 
|         var triangleCount = 8 * 3; | 
|         for (int i = 0, vIdx = 0; i < triangleCount - 6; i += 6, vIdx += 2) | 
|         { | 
|             vh.AddTriangle(vIdx + 1, vIdx, vIdx + 3); | 
|             vh.AddTriangle(vIdx, vIdx + 2, vIdx + 3); | 
|         } | 
|         vh.AddTriangle(8 - 1, 8 - 2, 1); | 
|         vh.AddTriangle(8 - 2, 0, 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, outterVertices, innerVertices); | 
|     } | 
|   | 
|     private bool Contains(Vector2 p, List<Vector3> outterVertices, List<Vector3> innerVertices) | 
|     { | 
|         var crossNumber = 0; | 
|         crossNumber += UIUtility.RayCrossingCount(p, innerVertices); | 
|         crossNumber += UIUtility.RayCrossingCount(p, outterVertices); | 
|         return (crossNumber & 1) == 1; | 
|     } | 
| } |