赞
踩
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));
}
}
}
}
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。