[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 }

posted on 2019-03-27 22:51 艰苦奋斗中 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lyh916/p/10611787.html

[UGUI]圆形Image相关推荐

  1. Unity UGUI 效果 之 UI 元素 多边形UI (例如雷达图,圆形,不规则多边形 UI等)显示 的简单实现的几种方法整理

    Unity UGUI 效果 之 UI 元素 多边形UI (例如雷达图,圆形,不规则多边形 UI等)显示 的简单实现的几种方法整理 目录 Unity UGUI 效果 之 UI 元素 多边形UI (例如雷 ...

  2. 【转】超简单利用UGUI制作圆形小地图

    http://sanwen.net/a/ithhtbo.html 由于UI都是Achor自己用PS做的,比较粗糙,大家见谅,不过丝毫不影响功能的实现,下面我们看看今天的笔记: 首先我们看看需要哪些组件 ...

  3. Unity 2D独立开发手记(九):UGUI仿GTA地图系统

    一直觉着GTA的小地图很方便,在地图上的图标能够实时反映出各种任务点.设施等的方位,那么我也仿照它的地图系统做一个简陋的. 还有,提前说一下,这篇文章面向至少用UGUI做过按钮点击事件的读者,因为一些 ...

  4. Unity新手引导(圆形指引、矩形指引)

    Unity新手引导(圆形指引.矩形指引) 声明:中心镂空为圆形或矩形,增加指引动画,基于UGUI 一.Shader 建立两个shader,命名为RectGuide.CircleGuide. RectG ...

  5. 关于UGUI的Image,Text (转雨凇momo)

    Image源码解读 接着我们来看看放在相同图集中的Sprite是如何合并DrawCall的,从原理上来讲,每个Mesh都需要给顶点设置UV信息,也就是说我们只需要将图集上的某个区域一一抠出来贴到Mes ...

  6. UGUI内核大探究(八)MaskableGraphic

    MaskableGraphic是UGUI的核心组件,它继承自Graphic.MaskableGraphic是一个抽象类,它的派生类有RawImage.Image.Text.顾名思义,MaskableG ...

  7. UGUI内核大探究(九)Image与RawImage

    Image组件是UGUI里最常用的组件(可能没有之一),我们知道其实还有一个RawImage组件.那么二者的区别是什么呢?之前的文章UGUI内核大探究(八)MaskableGraphic中我们提到过, ...

  8. Unity使用Cardboard、MojingSDK等VR插件的3DUI(UGUI)凝视效果的实现

    Cardboard是我接触VR开发最初接触到的SDK,因为对硬件和开发的要求比较低,所以很多的VR小游戏和应用(观影为主)都会基于Cardboard进行开发,但由于硬件设备的限制在用户交互上都会使用凝 ...

  9. Unity第三方库Procedural Circular Health Bar的核心组件添加到Image(UGUI)中时不能正确在Game窗口显示(显示色块)

    Procedural Circular Health Bar是一款分段圆形血量条的第三方package 有段时间可以免费录取,商品链接如下 Procedural Circular Health Bar ...

最新文章

  1. 一行代码实现Okhttp,Retrofit,Glide下载上传进度监听
  2. 如何使用Mybatis的拦截器实现数据加密与解密
  3. Matlab之switch-case语句
  4. 通过init进程看如何启动第一个应用程序
  5. “去除更多的鲜艳色彩和动态效果的搭配,精简用户使用步长,让软件更像是一件工具。(不排除以后更先进的吸引眼球的方式)“。
  6. 通过回调函数阻止进程创建(验证结束,方案完全可行)
  7. LeetCode MySQL 578. 查询回答率最高的问题
  8. 原来这就是比 ThreadLocal 更快的玩意
  9. c语言字 字符串转换成数组_C语言学习教程之详解C语言中的字符串数组
  10. 前苹果员工创办激光雷达公司,获4500万美元融资,曾参与苹果机密项目
  11. 力扣题目——107. 二叉树的层序遍历 II
  12. Error: Can’t resolve ‘./src’ in ‘E:\ASUS\Documents\VSCode files\WebPackProject’
  13. 最新版AltiumDesignerSummer9下载+破解
  14. 数学建模大赛准备方法及资源分享
  15. matlab控制读取数小数位,matlab输出的数值型矩阵中如何控制小数位数,以及对齐方式?...
  16. Odoo12社区版分拣单处理时生成欠单流程
  17. WordPress 前端投稿/编辑插件 DJD Site Post(支持游客和已注册用户)
  18. C#基础面试题(附答案)
  19. 《计算机网络参考模型》
  20. 如何设置自定义任务栏图标_如何为任何应用程序自定义Windows 7任务栏图标

热门文章

  1. oracle 数据回滚,恢复误删的数据,闪回表功能的使用
  2. [YTU]_2617( B C++时间类的运算符重载)
  3. toeplitz--生成托普利兹矩阵
  4. Python进阶02 文本文件的输入输出
  5. 特征值和特征向量(Eigenvalues and Eigenvectors)
  6. cart2pol函数
  7. cornerHarris函数
  8. k近邻法matlab_机器学习系列(一)K近邻算法(KNN,KNearestNeigh
  9. kubectl bash补全
  10. matlab数组操作