using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class UGUIPoplateMesh : MaskableGraphic, IPointerEnterHandler, IPointerExitHandler
{
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
for (int i = 0; i < vertexQuadList.Count; i++)
{
vh.AddUIVertexQuad(vertexQuadList[i]);
}
}
List<UIVertex[]> vertexQuadList = new List<UIVertex[]>();
Vector2 lastPoint = Vector2.zero;
Vector2 lastLineVect = Vector2.zero;
Vector3 lastNormal = Vector2.zero;
bool isPointerInCavnas = false;
bool isNewLine = false;
bool isFirstPoint = true;
public Camera uiCamera;
public float width = 2f;
protected override void Awake()
{
base.Awake();
vertexQuadList.Clear();
}
void Update()
{
if(!isPointerInCavnas)
return;
if(Input.GetMouseButtonUp(2))
{
vertexQuadList.Clear();
SetVerticesDirty();
isFirstPoint = true;
return;
}
if(Input.GetMouseButton(0))
{
var curPoint = GetScreenToLocalPoint(Input.mousePosition);
if(isFirstPoint)
{
lastPoint = curPoint;
isFirstPoint = false;
isNewLine = true;
return;
}
var vect = curPoint - lastPoint;
if(vect.magnitude < 16)
return;
var normal3 = Vector3.Cross(vect, Vector3.forward).normalized;
var normal = new Vector2(normal3.x, normal3.y);
var lastUpPoint = lastPoint + normal * width;
var lastDownPoint = lastPoint - normal * width;
var curUpPoint = curPoint + normal * width;
var curDownPoint = curPoint - normal * width;
if(vertexQuadList.Count > 0)
{
// 获取上一个线段与当前绘制的线段的角度
var angle = Vector3.Angle(lastLineVect, vect);
// 如果不是平行的 在这之间补一个三角形
if(angle != 0 || angle != 180)
{
var array = vertexQuadList[vertexQuadList.Count - 1];
// 获取上边是否相交和相交的点
bool upinter = FindIntersectionPoint(array[0].position, array[3].position, lastUpPoint, curUpPoint, out var upinterPoint);
// 获取下边是否相交和相交的点
bool downinter = FindIntersectionPoint(array[1].position, array[2].position, lastDownPoint, curDownPoint, out var downinterPoint);
// 根据相交点判断如何找补三角形
if(upinter)
{
array[2].position = upinterPoint - width * lastNormal * 2;
array[3].position = upinterPoint;
lastUpPoint = upinterPoint;
lastDownPoint = upinterPoint - width * normal3 * 2;
var vectQuad1 = new UIVertex[4];
vectQuad1[0] = GetUIVertex(upinterPoint);
vectQuad1[1] = GetUIVertex(array[2].position);
vectQuad1[2] = GetUIVertex(lastDownPoint);
vectQuad1[3] = GetUIVertex(upinterPoint);
vertexQuadList.Add(vectQuad1);
}
else if(downinter)
{
array[3].position = downinterPoint + width * lastNormal * 2;
array[2].position = downinterPoint;
lastUpPoint = downinterPoint + width * normal3 * 2;
lastDownPoint = downinterPoint;
var vectQuad1 = new UIVertex[4];
vectQuad1[0] = GetUIVertex(array[3].position);
vectQuad1[1] = GetUIVertex(downinterPoint);
vectQuad1[2] = GetUIVertex(lastUpPoint);
vectQuad1[3] = GetUIVertex(array[3].position);
vertexQuadList.Add(vectQuad1);
}
}
}
var vectQuad = new UIVertex[4];
vectQuad[0] = GetUIVertex(lastUpPoint);
vectQuad[1] = GetUIVertex(lastDownPoint);
vectQuad[2] = GetUIVertex(curDownPoint);
vectQuad[3] = GetUIVertex(curUpPoint);
vertexQuadList.Add(vectQuad);
lastNormal = normal;
lastLineVect = vect.normalized;
lastPoint = curPoint;
lastUpPoint = curUpPoint;
lastDownPoint = curDownPoint;
CLog.Log(1, lastUpPoint, lastDownPoint);
SetVerticesDirty();
}
}
bool FindIntersectionPoint(Vector3 A, Vector3 B, Vector3 C, Vector3 D , out Vector3 res)
{
Vector3 AB = B - A;
Vector3 CD = D - C;
res = Vector3.zero;
float t1, t2;
if (Vector3.Cross(AB, CD) == Vector3.zero)
{
// 矢量平行或共线,没有相交点
Debug.Log("Vectors are parallel or collinear, no intersection point.");
return false;
}
else
{
t1 = Vector3.Cross(C - A, CD).magnitude / Vector3.Cross(AB, CD).magnitude;
t2 = Vector3.Cross(A - C, AB).magnitude / Vector3.Cross(CD, AB).magnitude;
if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1)
{
// 有相交点
res = A + t1 * AB;
return true;
}
else
{
return false;
}
}
}
UIVertex GetUIVertex(Vector2 pos)
{
var uIVertex = new UIVertex();
uIVertex.color = color;
uIVertex.position = pos;
return uIVertex;
}
Vector2 GetScreenToLocalPoint(Vector3 v3)
{
RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, v3, uiCamera, out var point);
return point;
}
void IPointerEnterHandler.OnPointerEnter(PointerEventData eventData)
{
isPointerInCavnas = true;
}
void IPointerExitHandler.OnPointerExit(PointerEventData eventData)
{
isPointerInCavnas = false;
}
}