在Github中看到一个画图表(折线图,树状图,饼状图,雷达图)的插件。
看了底层使用UGUI中的重写了OnPopulateMesh(VertexHelper vh) 这个方法,然后用来绘制,今天学习了一下,很强大。
用到画线的功能,所以研究之后,改了一下,用来实现鼠标画线的功能。
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public enum LineType
{Straight,Smooth
}public class DrawLineComponent : Graphic
{[Header("线的属性")][SerializeField] private LineType lineType = LineType.Straight;[SerializeField] private Line line = new StraightLine();[SerializeField] protected float m_ChartWidth;[NonSerialized] private bool m_RefreshChart = false;public float chartWidth { get { return m_ChartWidth; } }public LineType LineType{get => lineType;set{lineType = value;if (value == LineType.Straight)line = new StraightLine();elseline = new SmoothLine();m_RefreshChart = true;}}protected override void Awake(){base.Awake();m_ChartWidth = rectTransform.sizeDelta.x;if (LineType == LineType.Smooth)line = new SmoothLine();}protected override void OnPopulateMesh(VertexHelper vh){vh.Clear();line.DrawLine(vh);}private void Update(){CheckRefreshChart();}protected void CheckRefreshChart(){if (m_RefreshChart){int tempWid = (int)chartWidth;rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, tempWid - 1);rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, tempWid);m_RefreshChart = false;}}public void AddPoint(Vector3 v3){line.AddPoint(v3);m_RefreshChart = true;}public void AddPoint(List<Vector3> points){line.AddPoint(points);m_RefreshChart = true;}public void SetSize(float size){line.size = size;m_RefreshChart = true;}public void SetColor(Color color){line.lineColor = color;m_RefreshChart = true;}public void SetSmoothness(float smoothness){if (LineType == LineType.Smooth)((SmoothLine)line).smoothness = smoothness;m_RefreshChart = true;}public void SetLineSmoothStyle(float smoothStyle){if (LineType == LineType.Smooth)((SmoothLine)line).lineSmoothStyle = smoothStyle;m_RefreshChart = true;}
}[System.Serializable]
public class Line
{[SerializeField]protected List<Vector3> dataPoints = new List<Vector3>();[SerializeField] public float size = 1;[SerializeField] public Color lineColor = Color.black;public virtual void DrawLine(VertexHelper vh){}public void AddPoint(Vector3 p){dataPoints.Add(p);}public void AddPoint(List<Vector3> points){dataPoints.AddRange(points);}
}
public class StraightLine : Line
{public override void DrawLine(VertexHelper vh){for (int i = 0; i < dataPoints.Count; i++){if (i < dataPoints.Count - 1){UIDrawLine.DrawLine(vh, dataPoints[i], dataPoints[i + 1], size, lineColor);}}}
}
public class SmoothLine:Line
{/// <summary>//曲线平滑度。值越小曲线越平滑,但顶点数也会随之增加。/// </summary>[SerializeField] public float smoothness = 2;/// <summary>/// 曲线平滑系数。通过调整平滑系数可以改变曲线的曲率,得到外观稍微有变化的不同曲线。/// </summary>[SerializeField] public float lineSmoothStyle = 2;private List<Vector3> bezierPoints = new List<Vector3>();public override void DrawLine(VertexHelper vh){Vector3 lp = ;Vector3 np = ;Vector3 llp = ;Vector3 nnp = ;for (int i = 0; i < dataPoints.Count; i++){if (i < dataPoints.Count - 1){llp = i > 1 ? dataPoints[i - 2] : lp;nnp = i < dataPoints.Count - 1 ? dataPoints[i + 1] : np;UIDrawLine.GetBezierList(ref bezierPoints, dataPoints[i], dataPoints[i + 1], llp, nnp, smoothness, lineSmoothStyle);for (int j = 0; j < bezierPoints.Count; j++){if (j < bezierPoints.Count - 1){UIDrawLine.DrawLine(vh, bezierPoints[j], bezierPoints[j + 1], size, lineColor);}}}}}}
画线的脚本
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 画线
///
/// </summary>
public class UIDrawLine
{private static UIVertex[] vertex = new UIVertex[4];public static void DrawLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, Color32 color){if (p1 == p2) return;Vector3 v = Vector3.Cross(p2 - p1, Vector3.forward).normalized * size;vertex[0].position = p1 - v;vertex[1].position = p2 - v;vertex[2].position = p2 + v;vertex[3].position = p1 + v;for (int j = 0; j < 4; j++){vertex[j].color = color;vertex[j].uv0 = ;}vh.AddUIVertexQuad(vertex);}public static void GetBezierList(ref List<Vector3> posList, Vector3 sp, Vector3 ep,Vector3 lsp, Vector3 nep, float smoothness = 2f, float k = 2.0f){float dist = Mathf.Abs(sp.x - ep.x);Vector3 cp1, cp2;var dir = (ep - sp).normalized;var diff = dist / k;if (lsp == sp){cp1 = sp + dist / k * dir * 1;cp1.y = sp.y;cp1 = sp;}else{cp1 = sp + (ep - lsp).normalized * diff;}if (nep == ep) cp2 = ep;else cp2 = ep - (nep - sp).normalized * diff;dist = Vector3.Distance(sp, ep);int segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness));if (segment < 1) segment = (int)(dist / 0.5f);if (segment < 4) segment = 4;GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);}public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep, int segment, Vector3 cp,Vector3 cp2){posList.Clear();if (posList.Capacity < segment + 1){posList.Capacity = segment + 1;}for (int i = 0; i < segment; i++){posList.Add((GetBezier2(i / (float)segment, sp, cp, cp2, ep)));}posList.Add(ep);}public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep){t = Mathf.Clamp01(t);var oneMinusT = 1f - t;return oneMinusT * oneMinusT * oneMinusT * sp +3f * oneMinusT * oneMinusT * t * p1 +3f * oneMinusT * t * t * p2 +t * t * t * ep;}
}
public class TestMouse : MonoBehaviour
{[SerializeField] private DrawLineComponent dl;void Start(){dl.SetSize(2);}void Update(){if(Input.GetMouseButton(0)){Debug.usePosition);dl.usePosition);}}
}
Demo下载链接
下载地址
本文发布于:2024-01-27 22:49:18,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17063669593117.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |