• Unity使用MaskableGraphic画一条带箭头的线


    请添加图片描述

    👉一、绘制箭头线段的原理

    利用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;
        }
    }
    
    
    • 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
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119

    将该脚本挂载到UI空物体对象上,调整其宽高(最好是2:1或者更高),设置箭头类型或颜色即可。

    2、实现效果

    右箭头:
    在这里插入图片描述

    左箭头:
    在这里插入图片描述
    左右双箭头:
    在这里插入图片描述

    👉三、推荐阅读

    当你理解了MaskableGraphic类绘制图形的原理之后,你就可以利用它来画出你想要的图案了。你也可以对本博客的画箭头代码加以拓展,画出渐变色的箭头线段或者任何你想要的箭头样式图案。下面是一些利用MaskableGraphic画其他图形的博客,供大家参考学习:

    Unity画一个矩形刻度尺

    Unity实现UI描边的方法

  • 相关阅读:
    泛型的使用
    基于Boostrap+Html的响应式Web电影网站设计
    SpringMVC
    【数据结构复习之路】线性表(严蔚敏版)万字详解&主打基础
    Vue+ ArcGIS JavaScript APi
    ssrf学习笔记总结
    解题元宇宙,网络游戏中的多元通信方案
    中国城市规划行业发展战略及前景趋势分析报告2022-2028年版
    安卓动态代理
    vcpkg: bootstrap-vcpkg.bat下载失败问题
  • 原文地址:https://blog.csdn.net/qq_42437783/article/details/125596848