[UGUI]圆形Image
参考链接:
http://www.cnblogs.com/leoin2012/p/6425089.html
前面说过Mask组件会影响性能:https://www.cnblogs.com/lyh916/p/10587632.html
因此,尽量少使用Mask,对于类似技能图标那样的圆形图片,可以考虑用本文的方式去实现。
1.CircleImage.cs
1 using UnityEngine; 2 using UnityEngine.UI; 3 using UnityEngine.Sprites; 4 using System.Collections.Generic; 5 6 public class CircleImage : Image { 7 8 public float fillPercent = 1f; //填充比例 9 public int fillNum = 100; //填充个数 10 private List<Vector2> outerVertexs; //圆上顶点列表 11 12 protected override void Awake() 13 { 14 base.Awake(); 15 outerVertexs = new List<Vector2>(); 16 } 17 18 protected override void OnPopulateMesh(VertexHelper toFill) 19 { 20 if (overrideSprite == null) 21 { 22 base.OnPopulateMesh(toFill); 23 return; 24 } 25 26 switch (type) 27 { 28 case Type.Simple: 29 GenerateSimpleSprite(toFill, preserveAspect); 30 break; 31 } 32 } 33 34 void GenerateSimpleSprite(VertexHelper vh, bool lPreserveAspect) 35 { 36 vh.Clear(); 37 outerVertexs.Clear(); 38 39 //计算准备 40 Vector4 uv = (overrideSprite != null) ? DataUtility.GetOuterUV(overrideSprite) : Vector4.zero; 41 42 float degreeDelta = 2 * Mathf.PI / fillNum; 43 int curNum = (int)(fillNum * fillPercent); 44 float width = rectTransform.rect.width; 45 float height = rectTransform.rect.height; 46 float radius = width * 0.5f; 47 48 float uvCenterX = (uv.x + uv.z) * 0.5f; 49 float uvCenterY = (uv.y + uv.w) * 0.5f; 50 float uvScaleX = (uv.z - uv.x) / width; 51 float uvScaleY = (uv.w - uv.y) / height; 52 53 //添加第一个点 54 UIVertex uiVertex = new UIVertex(); 55 uiVertex.color = color; 56 uiVertex.position = Vector2.zero; 57 uiVertex.uv0 = new Vector2(uvCenterX, uvCenterY); 58 vh.AddVert(uiVertex); 59 60 //添加圆上的点 61 int vertNum = (fillPercent == 1) ? curNum : curNum + 1; 62 for (int i = 1; i <= vertNum; i++) 63 { 64 float curDegree = (i - 1) * degreeDelta; 65 float cosA = Mathf.Cos(curDegree); 66 float sinA = Mathf.Sin(curDegree); 67 Vector2 curVertice = new Vector2(cosA * radius, sinA * radius); 68 69 uiVertex = new UIVertex(); 70 uiVertex.color = color; 71 uiVertex.position = curVertice; 72 uiVertex.uv0 = new Vector2(uvCenterX + curVertice.x * uvScaleX, uvCenterY + curVertice.y * uvScaleY); 73 vh.AddVert(uiVertex); 74 75 outerVertexs.Add(curVertice); 76 } 77 78 //连接点 79 for (int i = 1; i < vertNum; i++) 80 { 81 vh.AddTriangle(0, i + 1, i); 82 } 83 if (fillPercent == 1) 84 { 85 vh.AddTriangle(0, 1, curNum); 86 } 87 88 //连接点击区域 89 if (fillPercent < 1) 90 { 91 outerVertexs.Add(Vector2.zero); 92 } 93 } 94 95 public override bool IsRaycastLocationValid(Vector2 screenPoint, Camera eventCamera) 96 { 97 Sprite sprite = overrideSprite; 98 if (sprite == null) 99 return true; 100 101 Vector2 local; 102 RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, screenPoint, eventCamera, out local); 103 104 return MathTool.IsPointInPolygon(local, outerVertexs); 105 } 106 }
效果如下:
分析:
a.顶点数据
这里以pivot为(0.5,0.5)为例。在这种情况下,图片的位置中心和uv中心重合,即都在图片的中点处。因此这时位置和uv是成比例的,即uv.z - uv.x对应width,uv.w - uv.y对应height,这样就可以根据当前点的位置计算出对应的uv坐标。
关于圆上的顶点个数,当填充比例小于1时,顶点个数=三角形个数+1;当填充比例等于1时,顶点个数=三角形个数(因为点重合)
b.顶点连接
要按顺时针连接(顺时针表示正对屏幕,逆时针表示背对屏幕)。这里使用(0, i + 1, i)的顺序。
c.点击区域
使用这个算法:https://www.cnblogs.com/lyh916/p/10633132.html
要注意的是,当填充比例小于1时,要把原点也加上去,可以考虑一下下面的情况:
2.CircleImageEditor.cs
1 using UnityEditor; 2 using UnityEditor.UI; 3 4 [CustomEditor(typeof(CircleImage))] 5 public class CircleImageEditor : ImageEditor { 6 7 SerializedProperty fillPercent; 8 SerializedProperty fillNum; 9 10 protected override void OnEnable() 11 { 12 base.OnEnable(); 13 fillPercent = serializedObject.FindProperty("fillPercent"); 14 fillNum = serializedObject.FindProperty("fillNum"); 15 } 16 17 public override void OnInspectorGUI() 18 { 19 base.OnInspectorGUI(); 20 21 serializedObject.Update(); 22 23 fillPercent.floatValue = EditorGUILayout.Slider("填充比例", fillPercent.floatValue, 0, 1); 24 fillNum.intValue = EditorGUILayout.IntSlider("填充个数", fillNum.intValue, 1, 100); 25 26 serializedObject.ApplyModifiedProperties(); 27 } 28 }
转载于:https://www.cnblogs.com/lyh916/p/10611787.html
[UGUI]圆形Image相关推荐
- Unity UGUI 效果 之 UI 元素 多边形UI (例如雷达图,圆形,不规则多边形 UI等)显示 的简单实现的几种方法整理
Unity UGUI 效果 之 UI 元素 多边形UI (例如雷达图,圆形,不规则多边形 UI等)显示 的简单实现的几种方法整理 目录 Unity UGUI 效果 之 UI 元素 多边形UI (例如雷 ...
- 【转】超简单利用UGUI制作圆形小地图
http://sanwen.net/a/ithhtbo.html 由于UI都是Achor自己用PS做的,比较粗糙,大家见谅,不过丝毫不影响功能的实现,下面我们看看今天的笔记: 首先我们看看需要哪些组件 ...
- Unity 2D独立开发手记(九):UGUI仿GTA地图系统
一直觉着GTA的小地图很方便,在地图上的图标能够实时反映出各种任务点.设施等的方位,那么我也仿照它的地图系统做一个简陋的. 还有,提前说一下,这篇文章面向至少用UGUI做过按钮点击事件的读者,因为一些 ...
- Unity新手引导(圆形指引、矩形指引)
Unity新手引导(圆形指引.矩形指引) 声明:中心镂空为圆形或矩形,增加指引动画,基于UGUI 一.Shader 建立两个shader,命名为RectGuide.CircleGuide. RectG ...
- 关于UGUI的Image,Text (转雨凇momo)
Image源码解读 接着我们来看看放在相同图集中的Sprite是如何合并DrawCall的,从原理上来讲,每个Mesh都需要给顶点设置UV信息,也就是说我们只需要将图集上的某个区域一一抠出来贴到Mes ...
- UGUI内核大探究(八)MaskableGraphic
MaskableGraphic是UGUI的核心组件,它继承自Graphic.MaskableGraphic是一个抽象类,它的派生类有RawImage.Image.Text.顾名思义,MaskableG ...
- UGUI内核大探究(九)Image与RawImage
Image组件是UGUI里最常用的组件(可能没有之一),我们知道其实还有一个RawImage组件.那么二者的区别是什么呢?之前的文章UGUI内核大探究(八)MaskableGraphic中我们提到过, ...
- Unity使用Cardboard、MojingSDK等VR插件的3DUI(UGUI)凝视效果的实现
Cardboard是我接触VR开发最初接触到的SDK,因为对硬件和开发的要求比较低,所以很多的VR小游戏和应用(观影为主)都会基于Cardboard进行开发,但由于硬件设备的限制在用户交互上都会使用凝 ...
- Unity第三方库Procedural Circular Health Bar的核心组件添加到Image(UGUI)中时不能正确在Game窗口显示(显示色块)
Procedural Circular Health Bar是一款分段圆形血量条的第三方package 有段时间可以免费录取,商品链接如下 Procedural Circular Health Bar ...
最新文章
- 一行代码实现Okhttp,Retrofit,Glide下载上传进度监听
- 如何使用Mybatis的拦截器实现数据加密与解密
- Matlab之switch-case语句
- 通过init进程看如何启动第一个应用程序
- “去除更多的鲜艳色彩和动态效果的搭配,精简用户使用步长,让软件更像是一件工具。(不排除以后更先进的吸引眼球的方式)“。
- 通过回调函数阻止进程创建(验证结束,方案完全可行)
- LeetCode MySQL 578. 查询回答率最高的问题
- 原来这就是比 ThreadLocal 更快的玩意
- c语言字 字符串转换成数组_C语言学习教程之详解C语言中的字符串数组
- 前苹果员工创办激光雷达公司,获4500万美元融资,曾参与苹果机密项目
- 力扣题目——107. 二叉树的层序遍历 II
- Error: Can’t resolve ‘./src’ in ‘E:\ASUS\Documents\VSCode files\WebPackProject’
- 最新版AltiumDesignerSummer9下载+破解
- 数学建模大赛准备方法及资源分享
- matlab控制读取数小数位,matlab输出的数值型矩阵中如何控制小数位数,以及对齐方式?...
- Odoo12社区版分拣单处理时生成欠单流程
- WordPress 前端投稿/编辑插件 DJD Site Post(支持游客和已注册用户)
- C#基础面试题(附答案)
- 《计算机网络参考模型》
- 如何设置自定义任务栏图标_如何为任何应用程序自定义Windows 7任务栏图标