当前位置:网站首页>Unity使用MaskableGraphic画一条带箭头的线
Unity使用MaskableGraphic画一条带箭头的线
2022-07-06 19:19:00 【周周的Unity小屋】
一、绘制箭头线段的原理
利用UGUI的MaskableGraphic类我们可以重写OnPopulateMesh函数来绘制多个矩形面片,让多个矩形面片组成一根带箭头的线段。如下图:
在一个大矩形UI框内重画一个右箭头的原理是:
由R1、R2、R3和R4四个顶点画出右箭头的头部下半部分小矩形:
由R1、R5、R6和R7四个顶点画出右箭头的头部上半部分小矩形:
由R4、R8、R9和R7四个顶点画出箭杆小矩形:
这样,我们只需要用9个顶点信息绘制出3个小矩形来构成一个箭头样式的线段了。同理,将右箭头的顶点信息中的x轴坐标取反,就可以画出左箭头了;将左右箭头部分画出来,再画中间箭杆矩形就可以组成一个左右双箭头样式的线段。详细请看下面核心代码和实现效果。
二、核心脚本及实现效果
1、核心脚本
DrawArrow.cs脚本:
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 定义箭头方向的枚举
/// </summary>
public enum DirectionType
{
Right,
Left,
Both
}
public class DrawArrow : MaskableGraphic
{
[SerializeField]
private DirectionType arrowDirection = DirectionType.Right;//默认为右箭头
public DirectionType ArrowDirection
{
set
{
arrowDirection = value;
SetVerticesDirty();//设置箭头类型之后需要重新绘制顶点
}
}
public Color arrowColor = Color.black;//默认箭头颜色为黑色
public float arrowPixel = 1.0f;//默认箭头像素为1
private float width;
private float height;
protected override void OnPopulateMesh(VertexHelper vh)
{
base.OnPopulateMesh(vh);
vh.Clear();
width = rectTransform.rect.width;//获取该矩形UI的宽
height = rectTransform.rect.height;//获取该矩形UI的高
//定义右箭头坐标点
var R1 = new Vector3(width * 0.5f, 0, 0);//右箭头顶点共用点
var R2 = new Vector3(width * 0.5f - height * 0.5f, -height * 0.5f, 0);
var R3 = new Vector3(width * 0.5f - height * 0.5f - arrowPixel, -(height * 0.5f - arrowPixel), 0);
var R4 = new Vector3(width * 0.5f - arrowPixel, arrowPixel, 0);//矩形共用点
var R5 = new Vector3(width * 0.5f - height * 0.5f, height * 0.5f, 0);
var R6 = new Vector3(width * 0.5f - height * 0.5f - arrowPixel, height * 0.5f - arrowPixel, 0);
var R7 = new Vector3(width * 0.5f - arrowPixel, -arrowPixel, 0);//矩形共用点
var R8 = new Vector3(-width * 0.5f, arrowPixel, 0);
var R9 = new Vector3(-width * 0.5f, -arrowPixel, 0);
//定义左箭头坐标点,与右箭头顶点的X轴相反
var L1 = new Vector3(-R1.x, R1.y, R1.z);//左箭头顶点共用点
var L2 = new Vector3(-R2.x, R2.y, R2.z);
var L3 = new Vector3(-R3.x, R3.y, R3.z);
var L4 = new Vector3(-R4.x, R4.y, R4.z);//矩形共用点
var L5 = new Vector3(-R5.x, R5.y, R5.z);
var L6 = new Vector3(-R6.x, R6.y, R6.z);
var L7 = new Vector3(-R7.x, R7.y, R7.z);//矩形共用点
var L8 = new Vector3(-R8.x, R8.y, R8.z);
var L9 = new Vector3(-R9.x, R9.y, R9.z);
switch (arrowDirection)
{
case DirectionType.Right://绘制右箭头
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, R1, R2, R3, R4));//右箭头的头部下半部分矩形
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, R1, R5, R6, R7));//右箭头的头部上半部分矩形
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, R4, R8, R9, R7));//右箭头的箭杆矩形
break;
case DirectionType.Left://绘制左箭头
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, L1, L2, L3, L4));
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, L1, L5, L6, L7));
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, L4, L8, L9, L7));
break;
case DirectionType.Both://绘制左右双箭头
//右箭头部分两个矩形
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, R1, R2, R3, R4));
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, R1, R5, R6, R7));
//左箭头部分两个矩形
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, L1, L2, L3, L4));
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, L1, L5, L6, L7));
//中间箭杆矩形
vh.AddUIVertexQuad(GetRectangleQuad(arrowColor, R4, R7, L7, L4));
break;
}
}
/// <summary>
/// 获取矩形面片,四点顶点信息绘制成一个矩形
/// </summary>
private UIVertex[] GetRectangleQuad(Color _color, params Vector2[] vector2s)
{
UIVertex[] vertexs = new UIVertex[vector2s.Length];
for (int i = 0; i < vertexs.Length; i++)
{
vertexs[i] = GetUIVertex(vector2s[i], _color);
}
return vertexs;
}
/// <summary>
/// 获取 UI顶点
/// </summary>
/// <param name="point"></param>
/// <param name="color"></param>
/// <returns></returns>
private UIVertex GetUIVertex(Vector2 point, Color _color)
{
UIVertex vertex = new UIVertex
{
position = point,
color = _color,
uv0 = Vector2.zero
};
return vertex;
}
}
将该脚本挂载到UI空物体对象上,调整其宽高(最好是2:1或者更高),设置箭头类型或颜色即可。
2、实现效果
右箭头:
左箭头:
左右双箭头:
三、推荐阅读
当你理解了MaskableGraphic类绘制图形的原理之后,你就可以利用它来画出你想要的图案了。你也可以对本博客的画箭头代码加以拓展,画出渐变色的箭头线段或者任何你想要的箭头样式图案。下面是一些利用MaskableGraphic画其他图形的博客,供大家参考学习:
边栏推荐
- Unity webgl adaptive web page size
- Statistics of radar data in nuscenes data set
- The 8 element positioning methods of selenium that you have to know are simple and practical
- PSINS中19维组合导航模块sinsgps详解(滤波部分)
- 实施MES管理系统时,哪些管理点是需要注意的
- 6-6 vulnerability exploitation SSH security defense
- 导数、偏导数、方向导数
- Cloud Mail . NET Edition
- [node learning notes] the chokidar module realizes file monitoring
- 哈希表及完整注释
猜你喜欢
C#/VB. Net to delete watermarks in word documents
The annual salary of general test is 15W, and the annual salary of test and development is 30w+. What is the difference between the two?
Station B's June ranking list - feigua data up main growth ranking list (BiliBili platform) is released!
Compress JS code with terser
Redis入门完整教程:复制拓扑
用全连接+softmax对图片的feature进行分类
Redis入门完整教程:复制配置
从零安装Redis
Go swagger use
Django database (SQLite) basic introductory tutorial
随机推荐
Summary of basic debugging steps of S120 driver
Niuke programming problem -- double pointer of 101 must be brushed
慧通编程入门课程 - 2A闯关
基于ensp防火墙双击热备二层网络规划与设计
How to build a 32core raspberry pie cluster from 0 to 1
Redis入门完整教程:RDB持久化
从零安装Redis
差异与阵列和阵列结构和链表的区别
CDB PDB user rights management
How to design interface test cases? Teach you a few tips to draft easily
Common fitting models and application methods of PCL
leetcode:5. Longest palindrome substring [DP + holding the tail of timeout]
安全巡检的工作
Huitong programming introductory course - 2A breakthrough
Number theory --- fast power, fast power inverse element
MATLB|具有储能的经济调度及机会约束和鲁棒优化
AWS学习笔记(一)
数字滚动增加效果
The panel floating with the mouse in unity can adapt to the size of text content
一文读懂Faster RCNN