UI元素之间连线
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Assertions;
namespace MyTest
{
public class CreateLine : MonoBehaviour
{
public RectTransform line;
public RectTransform startRT;
public RectTransform endRT;
float rectHalfWidth, rectHalfHeight;
float[] rectAngle = new float[4];
void Start()
{
Assert.IsTrue(startRT.rect.width == endRT.rect.width && startRT.rect.height == endRT.rect.height &&
startRT.localScale.x == endRT.localScale.x && startRT.localScale.y == endRT.localScale.y,
$"{nameof(startRT)}与{nameof(endRT)}的大小、缩放需要一致");
rectHalfWidth = startRT.rect.width * startRT.localScale.x / 2;
rectHalfHeight = startRT.rect.height * startRT.localScale.y / 2;
Vector3[] corners = new Vector3[4];
startRT.GetLocalCorners(corners);
for (int i = 0; i < corners.Length; i++)
{
rectAngle[i] = deg(Mathf.Atan2(corners[i].y, corners[i].x));
}
initDrag();
}
void Update()
{
setLine(line, startRT, endRT);
}
void setLine(RectTransform line, RectTransform startRT, RectTransform endRT)
{
Vector2 endDir = endRT.position - startRT.position;
float lineLength = Vector3.Distance(startRT.localPosition, endRT.localPosition) / line.localScale.x;
endDir = endDir.normalized;
line.position = (startRT.position + endRT.position) / 2;
float angle = deg(Mathf.Atan2(endDir.y, endDir.x));
line.transform.rotation = Quaternion.Euler(0, 0, angle);
elimiOverlay(angle, ref lineLength);
line.sizeDelta = new Vector2(lineLength, line.sizeDelta.y);
}
void elimiOverlay(float angle, ref float lineLength)
{
float elimiLength;
if (angle < rectAngle[1] && angle > rectAngle[2] || angle > rectAngle[0] && angle < rectAngle[3])
{
elimiLength = rectHalfHeight / Mathf.Cos(rad(90 - Mathf.Abs(angle))) / line.localScale.x;
}
else
{
if (Mathf.Abs(angle) > 90)
elimiLength = rectHalfWidth / Mathf.Cos(rad(180 - Mathf.Abs(angle))) / line.localScale.x;
else
elimiLength = rectHalfWidth / Mathf.Cos(rad(Mathf.Abs(angle))) / line.localScale.x;
}
lineLength -= elimiLength * 2;
}
float deg(float x)
{
return x * Mathf.Rad2Deg;
}
float rad(float x)
{
return x * Mathf.Deg2Rad;
}
void initDrag()
{
startRT.gameObject.AddComponent<UIDrag>();
endRT.gameObject.AddComponent<UIDrag>();
}
}
}
public class UIDrag : MonoBehaviour, IBeginDragHandler, IDragHandler
{
private Vector2 offset = Vector2.zero;
void IBeginDragHandler.OnBeginDrag(PointerEventData eventData)
{
offset = transform.position;
offset -= eventData.position;
}
void IDragHandler.OnDrag(PointerEventData eventData)
{
this.transform.position = eventData.position + offset;
}
}