Unity画曲线插件Vectrosity

Unity自带的画线组件LineRenderer主要用于在3D空间中画线,在UI上使用并不方便,只能显示在UI前或者UI后,没法做到在图片之间穿插,如图:
在这里插入图片描述在这里插入图片描述

商店地址:Vectrosity

直线

Vectrosity可以方便的在UI上 画线,并可以在图片之间穿插,如图,创建的线夹在了两个图片中间。
在这里插入图片描述

//在LineRoot上添加该脚本
public class VectrisityTest : MonoBehaviour
{
    
    
    void Start()
    {
    
    
    	//定义线的路径
        var linePoints = new List<Vector2>();
        linePoints.Add (new Vector2(-500, 0));
        linePoints.Add (new Vector2(500, 0));
        
        var line = new VectorLine("Line", linePoints, 5.0f);
        line.color = Color.red;
        SetLineParent(line, transform);
        
        line.Draw();
    }
    
    private void SetLineParent(VectorLine line, Transform parent)
    {
    
    
         line.rectTransform.SetParent(parent);
         line.rectTransform.localPosition = Vector3.zero;
         //如果线在RectMask2D下裁剪的话,需要保证它一直在裁剪区域内
         line.rectTransform.sizeDelta = new Vector2(1000f, 1000f);
         line.rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
         line.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
         line.rectTransform.pivot = new Vector2(0.5f, 0.5f);
         line.rectTransform.anchoredPosition = Vector2.zero;
         line.rectTransform.localScale = Vector3.one;
     }
}

API详情可以参考这篇文章:Unity画线插件Vectrosity的API详解

曲线

使用MakeArc可以画出一个圆或椭圆的一部分,该函数以上方为0度,且只能顺时针画曲线,这条曲线就是从270度画到90度。
在这里插入图片描述
Unity中实现该效果
在这里插入图片描述
注意这里LineRoot的Pos Z设置为-1,是为了打断合批,合批会导致曲线画在最前面,层级关系就不对了。
在这里插入图片描述
这里用到的图片是插件demo中自带的图片,图片边缘做了模糊可以让曲线看起来更加平滑。

public class VectrisityTest : MonoBehaviour
{
    
    
    public Image imgLine;
    
    void Start()
    {
    
    
        DrawArc();
    }

    private void DrawArc()
    {
    
    
        //分段的数量,曲线也是一段段直线构成,分段的数量越多,曲线越平滑
        int segments = 50;
        //绘制曲线用到的点的数量,如果曲线分为3段,那它至少有3 + 1个点
        var linePoints = new List<Vector2>(segments + 1);

        var line = new VectorLine("Line", linePoints, imgLine.mainTexture, 5.0f, LineType.Continuous, Joins.Fill);
        line.color = Color.red;
        SetLineParent(line, transform);
        float radius = 300f;
        //开始和结束角度
        float startDegrees = 270;
        float endDegrees = 90;
        line.MakeArc (Vector3.zero, radius, radius, startDegrees, endDegrees);
        
        line.Draw();
    }
    
    private void SetLineParent(VectorLine line, Transform parent)
    {
    
    
         line.rectTransform.SetParent(parent);
         line.rectTransform.localPosition = Vector3.zero;
         //如果线在RectMask2D下裁剪的话,需要保证它一直在裁剪区域内
         line.rectTransform.sizeDelta = new Vector2(1000f, 1000f);
         line.rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
         line.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
         line.rectTransform.pivot = new Vector2(0.5f, 0.5f);
         line.rectTransform.anchoredPosition = Vector2.zero;
         line.rectTransform.localScale = Vector3.one;
     }
}

多段线

一个VectorLine对象画多段连续的线,这里需要注意线上点的先后顺序。
在这里插入图片描述

public class VectrisityTest : MonoBehaviour
{
    
    
    public Image imgLine1;
    public Image imgLine2;

    private VectorLine _line;
    
    void Start()
    {
    
    
        DrawMultiSegment();
    }

    private void DrawMultiSegment()
    {
    
    
        //先画直线
        var linePoints = new List<Vector2>();
        linePoints.Add(new Vector2(0, 0));
        linePoints.Add(new Vector2(-300, 0));
        _line = new VectorLine("Line", linePoints, imgLine1.mainTexture, 5.0f, LineType.Continuous, Joins.Fill);
        _line.color = Color.red;
        SetLineParent(_line, transform);
        
        //再画曲线
        int segments = 50;
        //index是曲线开始点的下标
        int index = _line.points2.Count;
        for (int i = 0; i < segments + 1; ++i)
        {
    
    
            _line.points2.Add(Vector2.zero);
        }
        float radius = 300f;
        //开始和结束角度
        float startDegrees = 270;
        float endDegrees = 90;
        _line.MakeArc (Vector3.zero, radius, radius, startDegrees, endDegrees, segments, index);
        _line.Draw();
    }
    
    private void SetLineParent(VectorLine line, Transform parent)
    {
    
    
        line.rectTransform.SetParent(parent);
        line.rectTransform.localPosition = Vector3.zero;
        line.rectTransform.offsetMin = Vector2.zero;
        line.rectTransform.offsetMax = Vector2.zero;
        line.rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
        line.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
        line.rectTransform.pivot = Vector2.zero;
        line.rectTransform.anchoredPosition = Vector2.zero;
        line.rectTransform.localScale = Vector3.one;
    }

    /// <summary>
    /// 运行时改变线
    /// </summary>
    public void OnButtonClick()
    {
    
    
        _line.texture = imgLine2.mainTexture;
        _line.lineWidth = 10f;
        _line.color = Color.white;
        _line.Draw();
    }
}

逆时针

为了支持逆时针画曲线,需要对源码进行一点扩展,添加一个partial 类,复制源码并进行一点小修改,这样调用MakeArcCounterClockwise 就可以逆时针画曲线了。

namespace Vectrosity
{
    
    
    public partial class VectorLine
    {
    
    
        /// <summary>
        /// 逆时针生成弧线
        /// </summary>
        public void MakeArcCounterClockwise (Vector3 origin, float xRadius, float yRadius, float startDegrees, float endDegrees, int segments, int index) {
    
    
            MakeEllipseCounterClockwise (origin, Vector3.forward, xRadius, yRadius, startDegrees, endDegrees, segments, 0.0f, index);
        }
        
        /// <summary>
		/// 逆时针生成椭圆
		/// </summary>
		private void MakeEllipseCounterClockwise (Vector3 origin, Vector3 upVector, float xRadius, float yRadius, float startDegrees, float endDegrees, int segments, float pointRotation, int index) {
    
    
			if (segments < 3) {
    
    
				Debug.LogError ("VectorLine.MakeEllipse needs at least 3 segments");
				return;
			}
			if (!CheckArrayLength (FunctionName.MakeEllipse, segments, index)) {
    
    
				return;
			}
			
			float totalDegrees, p;
			startDegrees = Mathf.Repeat (startDegrees, 360.0f);
			endDegrees = Mathf.Repeat (endDegrees, 360.0f);
			if (startDegrees == endDegrees) {
    
    
				totalDegrees = 360.0f;
				p = -pointRotation * Mathf.Deg2Rad;
			}
			else {
    
    
				// totalDegrees = (endDegrees > startDegrees)? endDegrees - startDegrees : (360.0f - startDegrees) + endDegrees;
				totalDegrees = endDegrees < startDegrees ? Mathf.Abs(endDegrees - startDegrees) : Mathf.Abs(startDegrees + 360 - endDegrees);
				p = startDegrees * Mathf.Deg2Rad;
			}
			float radians = (totalDegrees / segments) * Mathf.Deg2Rad;
			
			if (m_lineType != LineType.Discrete) {
    
    
				if (startDegrees != endDegrees) {
    
    
					segments++;
				}
				int i = 0;
				if (m_is2D) {
    
    
					Vector2 v2Origin = origin;
					for (i = 0; i < segments; i++) {
    
    
						m_points2[index+i] = v2Origin + new Vector2(.5f + Mathf.Sin(p)*xRadius, .5f + Mathf.Cos(p)*yRadius);
						// p += radians;
						p -= radians;
					}
					
					if (m_lineType != LineType.Points && startDegrees == endDegrees) {
    
    	// Copy point when making an ellipse so the shape is closed
						m_points2[index+i] = m_points2[index+(i-segments)];
					}
				}
				else {
    
    
					var thisMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.LookRotation(-upVector, upVector), Vector3.one);
					for (i = 0; i < segments; i++) {
    
    
						m_points3[index+i] = origin + thisMatrix.MultiplyPoint3x4(new Vector3(Mathf.Sin(p)*xRadius, Mathf.Cos(p)*yRadius, 0.0f));
						p += radians;
					}
					if (m_lineType != LineType.Points && startDegrees == endDegrees) {
    
    	// Copy point when making an ellipse so the shape is closed
						m_points3[index+i] = m_points3[index+(i-segments)];
					}
				}
			}
			// Discrete
			else {
    
    
				if (m_is2D) {
    
    
					Vector2 v2Origin = origin;
					for (int i = 0; i < segments*2; i++) {
    
    
						m_points2[index+i] = v2Origin + new Vector2(.5f + Mathf.Sin(p)*xRadius, .5f + Mathf.Cos(p)*yRadius);
						p += radians;
						i++;
						m_points2[index+i] = v2Origin + new Vector2(.5f + Mathf.Sin(p)*xRadius, .5f + Mathf.Cos(p)*yRadius);
					}
				}
				else {
    
    
					var thisMatrix = Matrix4x4.TRS(Vector3.zero, Quaternion.LookRotation(-upVector, upVector), Vector3.one);
					for (int i = 0; i < segments*2; i++) {
    
    
						m_points3[index+i] = origin + thisMatrix.MultiplyPoint3x4(new Vector3(Mathf.Sin(p)*xRadius, Mathf.Cos(p)*yRadius, 0.0f));
						p += radians;
						i++;
						m_points3[index+i] = origin + thisMatrix.MultiplyPoint3x4(new Vector3(Mathf.Sin(p)*xRadius, Mathf.Cos(p)*yRadius, 0.0f));
					}
				}
			}
		}
    }
}

猜你喜欢

转载自blog.csdn.net/sinat_34014668/article/details/126329739