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