﻿///按钮多边形点击方案，注意Canvas模式应该是Screen Space - Camera  需设置 Render Camera
///选中按钮右键UI->变更为多边形按钮，编辑子物体的Collider2D即可
///如果无法编辑Collider 则是Unity编辑器bug 切换下Unity编辑器的布局模式，即可恢复正常


using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace TyphoonUI
{
    /// <summary>
    /// 多边形按钮图片
    /// </summary>
    [RequireComponent(typeof(PolygonCollider2D))]
    public class PolygonButtonImage : Image
    {
        private PolygonCollider2D areaPolygon;

        protected PolygonButtonImage()
        {
            useLegacyMeshGeneration = true;
        }

        private PolygonCollider2D Polygon
        {
            get
            {
                if (areaPolygon != null)
                    return areaPolygon;

                areaPolygon = GetComponent<PolygonCollider2D>();
                return areaPolygon;
            }
        }


        protected override void OnPopulateMesh(VertexHelper vh)
        {
            vh.Clear();
        }

        public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera)
        {
            return Polygon.OverlapPoint(eventCamera.ScreenToWorldPoint(screenPoint));
        }

        //矩形适配到多边形
        public void RectFitPloy()
        {
            float offsetX = 0;
            float offsetY = 0;

            for (int i = 0; i < Polygon.points.Length; i++)
            {
                Vector2 point = Polygon.points[i];
                offsetX = Mathf.Max(Mathf.Abs(point.x), offsetX);
                offsetY = Mathf.Max(Mathf.Abs(point.y), offsetY);
            }

            rectTransform.sizeDelta = new Vector2(offsetX * 2, offsetY * 2);
        }

        public void CloseChildRaycastTarget()
        {
            bool temOn = raycastTarget;
            // 关闭原来button的射线检测
            var graphics = transform.GetComponentsInChildren<Graphic>();
            foreach (var graphic in graphics)
            {
                graphic.raycastTarget = false;
            }

            raycastTarget = temOn;
        }

#if UNITY_EDITOR
        protected override void Reset()
        {
            base.Reset();
            transform.localPosition = Vector3.zero;
            var w = rectTransform.sizeDelta.x * 0.5f + 0.1f;
            var h = rectTransform.sizeDelta.y * 0.5f + 0.1f;
            Polygon.points = new[]
            {
                new Vector2(-w, -h),
                new Vector2(w, -h),
                new Vector2(w, h),
                new Vector2(-w, h)
            };
        }
#endif
    }
#if UNITY_EDITOR
    [CustomEditor(typeof(PolygonButtonImage), true)]
    [CanEditMultipleObjects]
    public class CustomRaycastFilterInspector : Editor
    {
        public override void OnInspectorGUI()
        {
            //base.OnInspectorGUI();

            PolygonButtonImage ployImg = target as PolygonButtonImage;
            //GUILayout.BeginHorizontal();
            //GUILayout.Label("Material");
            //ployImg.material = EditorGUILayout.ObjectField(ployImg.material, typeof(Material)) as Material;
            //GUILayout.EndHorizontal();
            GUILayout.Space(5);
            GUILayout.BeginHorizontal();
            GUILayout.Label("RaycastTarget");
            ployImg.raycastTarget = EditorGUILayout.Toggle(ployImg.raycastTarget);
            GUILayout.EndHorizontal();
            GUILayout.Space(5);
            //GUILayout.BeginHorizontal();
            ////GUILayout.Label("Color");
            //ployImg.color = EditorGUILayout.ColorField("Color", ployImg.color);
            //GUILayout.EndHorizontal();


            //注意事项
            GUILayout.Label("注意1：检测范围只在Rect框内");
            GUILayout.Label("相机方案只适合：Screen Space - Camera ");
            if (GUILayout.Button("Rect匹配到多边形大小", GUILayout.Height(30)))
            {
                ployImg.RectFitPloy();
            }

            if (GUILayout.Button("关闭子层渲染射线检测", GUILayout.Height(30)))
            {
                ployImg.CloseChildRaycastTarget();
            }
        }
    }

    public class NonRectAngularButtonImageHelper
    {
        [MenuItem("GameObject/UI/PloygonButton")]
        public static void CreateNonRectAngularButtonImage()
        {
            var goRoot = Selection.activeGameObject;
            GameObject polygon = new GameObject("PloygonButton");
            polygon.AddComponent<PolygonCollider2D>();
            polygon.AddComponent<PolygonButtonImage>();
            polygon.AddComponent<PolyImageButton>();
            polygon.transform.SetParent(goRoot.transform);
            polygon.transform.localPosition = Vector3.zero;
            polygon.transform.localScale = Vector3.one;
            polygon.transform.localEulerAngles = Vector3.zero;
            //设置锚点方案，注意rect transfrom的框必须包住多边形，否则超出的部分无效
            //polygon.GetComponent<RectTransform>().SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, 0, 0);
            //polygon.GetComponent<RectTransform>().SetInsetAndSizeFromParentEdge(RectTransform.Edge.Top, 0, 0);
            //polygon.GetComponent<RectTransform>().SetInsetAndSizeFromParentEdge(RectTransform.Edge.Right, 0, 0);
            //polygon.GetComponent<RectTransform>().SetInsetAndSizeFromParentEdge(RectTransform.Edge.Bottom, 0, 0);
            //polygon.GetComponent<RectTransform>().anchorMin = new Vector2(0, 0);
            //polygon.GetComponent<RectTransform>().anchorMax = new Vector2(1, 1);
        }
    }

#endif
}