当前位置:   article > 正文

Unity画曲线插件Vectrosity_unity vectrosity

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;
     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

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;
     }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

多段线

一个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();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

逆时针

为了支持逆时针画曲线,需要对源码进行一点扩展,添加一个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));
					}
				}
			}
		}
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/580276
推荐阅读
相关标签
  

闽ICP备14008679号