最近工程需要用到一个多边形用来查看角色属性,于是就研究了下Mesh用网格做了一个。遗憾的的 UGUI 渲染不了 3D 物体,然后又用了一段时间研究了下UGUI的网格绘制。

不过终于还是完成了,虽然有些瑕疵…… 好吧 有很大的问题 UV 需要自己计算。(如果有朋友精通这一块,希望能帮忙改进一下)

下边是5.2以下版本使用 的

5.2(包括)以上的 请点击这个连接

 在Unity中一个Mesh使用3个顶点就能画出来,但是UGUI需要使用四个顶点才行,所以在画一些特殊模型的时候就会产生一些废点(对图形没影响但是必须存在)。

下面要开始了。额……再等等,先让我借用几张图

Ok 先上使用教

先添加个这个

然后在这下边创建个空物体

然后添加这个脚本

然后就可以编辑这个脚本的属性 实现不同的多边形啦

使用polygon脚本 可以实现很多种形状 比如这些:

注意:上边这些都是UGUI,并不是模型网格;

5.2的UGUIAPI改动比较大所以不能想想兼容,我是在原作者的代码基础上改的。(希望原作者不会介意……额 我还是发个邮件说一下吧!!!!!!)

使用步骤和上边一样,这两个具有相同的问题就是UV的贴的时候没有贴好(原谅我这个数学渣渣),在原基础上增加了顶点网格的设置,其余的没有更改。

5.2(包涵)以上版本的 在上边的连接可以下载到 ,下边是5.2以下版本的。

 

  1. //*********************************************************************
  2. //
  3. // ScriptName : UIPolygonPast
  4. //
  5. // 筱程
  6. //
  7. //*********************************************************************
  8.  
  9. using UnityEngine;
  10. using UnityEngine.UI;
  11. using System.Collections.Generic;
  12. public class UIPolygonPast : MaskableGraphic
  13. {
  14.  
  15. List<Vector2> pointPosition = new List<Vector2>();
  16. List<Vector2> Vertex = new List<Vector2>();
  17. List<Vector2> UV = new List<Vector2>();
  18. // 是否使用顶点画 默认是不使用
  19. // 使用需要用户自己传入顶点位置
  20. // 否则会根据顶点数目 以零点位置自动计算圆形顶点位置
  21. [SerializeField]
  22. Texture m_Textrue;
  23.  
  24. public bool usingVertex;
  25.  
  26. // 是否中空
  27. public bool fill = true;
  28.  
  29. // 顶点数目
  30. [Range(, )]
  31. public int sides = ;
  32. // 选择角度
  33. [Range(, )]
  34. public float Rotation = ;
  35. // 边缘厚度
  36. [Range(, )]
  37. public float Thickness = ;
  38. // 顶点距离
  39. [Range(, )]
  40. public float[] VerticesDistances = new float[];
  41.  
  42. private float size = 1f;
  43. public override Texture mainTexture {
  44. get {
  45. return m_Textrue == null ? s_WhiteTexture : m_Textrue;
  46. }
  47. }
  48. public Texture texture {
  49. get {
  50. return m_Textrue;
  51. }
  52. set {
  53. if (m_Textrue == value)
  54. return;
  55. m_Textrue = value;
  56. SetVerticesDirty();
  57. SetMaterialDirty();
  58. }
  59. }
  60. /// <summary>
  61. /// 设置图片顶点
  62. /// </summary>
  63. /// <param name="_Vertex"></param>
  64. public void DrwaPolyonVertex(List<Vector2> _Vertex) {
  65. DrwaPolyonVertex(_Vertex, null);
  66. }
  67. /// <summary>
  68. /// 设置图片顶点
  69. /// </summary>
  70. /// <param name="_Vertex">顶点</param>
  71. /// /// <param name="_UV">UI</param>
  72. public void DrwaPolyonVertex(List<Vector2> _Vertex,List<Vector2> _UV) {
  73. Vertex = _Vertex;
  74. UV = _UV;
  75. usingVertex = true;
  76. }
  77. /// <summary>
  78. /// 设置顶点数目
  79. /// </summary>
  80. /// <param name="_sides"></param>
  81. public void DrwaPolygon(int _sides) {
  82. DrwaPolygon(_sides, null);
  83. }
  84. /// <summary>
  85. /// 设置顶点数目
  86. /// </summary>
  87. /// <param name="_sides"></param>
  88. /// <param name="_VerticesDistances">顶点距离信息</param>
  89. public void DrwaPolygon(int _sides, float[] _VerticesDistances) {
  90. DrwaPolygon(_sides, _VerticesDistances, );
  91. }
  92. /// <summary>
  93. /// 设置顶点数目
  94. /// </summary>
  95. /// <param name="_sides"></param>
  96. /// <param name="_VerTicesDstances">顶点距离信息</param>
  97. /// <param name="_Rotation">顶点旋转</param>
  98. public void DrwaPolygon(int _sides, float[] _VerTicesDstances,float _Rotation) {
  99. sides = _sides;
  100. if (_VerTicesDstances != null)
  101. VerticesDistances = _VerTicesDstances;
  102. Rotation = _Rotation;
  103. usingVertex = false;
  104. }
  105. private Vector2 CalculatedPosition(Vector2 p1, Vector2 p2, Rect rect) {
  106. p1.x *= rect.width;
  107. p1.y *= rect.height;
  108. return p1;
  109. }
  110.  
  111. // UI网格都是四边形,所以需要四个顶点
  112. // 但是我们只需要三个顶点,所以就需要添加一个废点
  113. // 否则不能组成网格
  114. // 最后所有点数的总和应该是4的倍数
  115. protected override void OnFillVBO(List<UIVertex> vbo) {
  116. vbo.Clear();
  117.  
  118. if (usingVertex) {
  119. VerterxDrwa(ref vbo);
  120. } else {
  121. VerterxNumberDrwa(ref vbo);
  122. }
  123. }
  124. // 用顶点画
  125. private void VerterxDrwa(ref List<UIVertex> vbo) {
  126. Vector2 pos1 = Vector2.zero;
  127. Vector2 pos2 = Vector2.zero;
  128. Vector2 pos3 = Vector2.zero;
  129. Vector2 pos4 = Vector2.zero;
  130. if (Vertex.Count == ) {
  131. pointPosition.Clear();
  132. pointPosition.Add(new Vector2(, -) / 2f);
  133. pointPosition.Add(new Vector2(-, -0.5f) / 2f);
  134.  
  135. pointPosition.Add(new Vector2(-, 0.5f) / 2f);
  136. pointPosition.Add(new Vector2(, ) / 2f);
  137. pointPosition.Add(new Vector2(, 0.5f) / 2f);
  138. pointPosition.Add(new Vector2(, -0.5f) / 2f);
  139. } else {
  140. pointPosition.Clear();
  141. pointPosition = Vertex;
  142. }
  143.  
  144. for (int i = ; i < pointPosition.Count; i++) {
  145. Vector2 pos = pointPosition[i];
  146. pointPosition[i] = CalculatedPosition(pos, rectTransform.pivot, rectTransform.rect);
  147. }
  148. int count = pointPosition.Count;
  149. Vector2 uv1 = new Vector2(, );
  150. Vector2 uv2 = new Vector2(, );
  151. Vector2 uv3 = new Vector2(, );
  152. Vector2 uv4 = new Vector2(, );
  153. for (int i = ; i < count - ; i++) {
  154.  
  155. pos1 = pointPosition[i];
  156. pos2 = pointPosition[i] + ( pointPosition[i] - Vector2.zero ) * -0.2f;
  157. pos3 = Vector2.zero;
  158. pos4 = pointPosition[i + ];
  159. if (UV != null && count==UV.Count) {
  160. uv3 = new Vector2(0.5f, 0.5f);
  161. uv1 = UV[i];
  162. uv4 = UV[i + ];
  163. uv2 = uv1 + ( uv1 - uv3 ) * -0.2f;
  164. }
  165. AddUIVerterx(ref vbo, new Vector2[] { pos1, pos2, pos3, pos4 }, new Vector2[] { uv1, uv2, uv3, uv4 });
  166. }
  167.  
  168. pos1 = pointPosition[count - ];
  169. pos2 = pointPosition[count - ] + ( pointPosition[count - ] - Vector2.zero ) * -0.2f;
  170. pos3 = Vector2.zero;
  171. pos4 = pointPosition[];
  172. if (UV != null && count == UV.Count) {
  173. uv1 = UV[count - ];
  174. uv4 = UV[];
  175. uv2 = uv1 + ( uv1 - uv3 ) * -0.2f;
  176. }
  177. AddUIVerterx(ref vbo, new Vector2[] { pos1, pos2, pos3, pos4 }, new Vector2[] { uv1, uv2, uv3, uv4 });
  178. }
  179. // 用顶点数画多边形
  180. private void VerterxNumberDrwa(ref List<UIVertex> vbo) {
  181.  
  182. float degrees = 360f / sides;
  183.  
  184. size = rectTransform.rect.width > rectTransform.rect.height ? rectTransform.rect.height : rectTransform.rect.width;
  185. Thickness = Mathf.Clamp(Thickness, , size / );
  186.  
  187. if (VerticesDistances == null || VerticesDistances.Length != sides + ) {
  188. VerticesDistances = new float[sides + ];
  189. for (int i = ; i < sides; i++)
  190. VerticesDistances[i] = ;
  191. }
  192. VerticesDistances[sides] = VerticesDistances[];
  193. Vector2 pos1 ;
  194. Vector2 pos2 ;
  195. Vector2 pos3 ;
  196. Vector2 pos4 ;
  197. Vector2 lastPosx = Vector2.zero;
  198. Vector2 lastPosy = Vector2.zero;
  199. Vector2 uv1 = new Vector2(, );
  200. Vector2 uv2 = new Vector2(, );
  201. Vector2 uv3 = new Vector2(, );
  202. Vector2 uv4 = new Vector2(, );
  203. //Vector2 lastuv = new Vector2(0.5f, 0.5f);
  204. for (int i = ; i <= sides; i++) {
  205.  
  206. float outer = -rectTransform.pivot.x * size * VerticesDistances[i];
  207. float inner = -rectTransform.pivot.x * size * VerticesDistances[i] + Thickness;
  208. float rad = Mathf.Deg2Rad * ( i * degrees + Rotation );
  209. float c = Mathf.Cos(rad);
  210. float s = Mathf.Sin(rad);
  211. pos1 = lastPosx;
  212. pos2 = new Vector2(outer * c, outer * s);
  213.  
  214. if (fill) {
  215. pos3 = Vector2.zero;
  216. pos4 = Vector2.zero;
  217. } else {
  218. pos3 = new Vector2(inner * c, inner * s);
  219. pos4 = lastPosy;
  220. }
  221. #region
  222. //int x = (int) (pos1.x < 0 ? pos1.x * -1 : pos1.x * 2);
  223. //int y = (int)( pos1.y < 0 ? pos1.y * -1 : pos1.y * 2 );
  224.  
  225. //float uvx = 0;
  226. //float uvy = 0;
  227. // if (x != 0) {
  228. // uvx =x / size;
  229. // }
  230. // if (y != 0) {
  231. // uvy =y / size;
  232. // }
  233.  
  234. //uv2 = new Vector2(uvx, uvy);
  235. //uv1 = lastuv;
  236. //lastuv = uv2;
  237. #endregion
  238. lastPosx = pos2;
  239. lastPosy = pos3;
  240. AddUIVerterx(ref vbo, new Vector2[] { pos1, pos2, pos3, pos4 }, new Vector2[] { uv1, uv2, uv3, uv4 });
  241. }
  242. }
  243. private void AddUIVerterx(ref List<UIVertex> vbo, Vector2[] pos, Vector2[] uv = null) {
  244. UIVertex vert = UIVertex.simpleVert;
  245. for (int i = ; i < pos.Length; i++) {
  246. vert.position = pos[i];
  247. vert.color = color;
  248. if (uv != null && uv.Length == pos.Length)
  249. vert.uv0 = uv[i];
  250. vbo.Add(vert);
  251. }
  252. }
  253. }

Unity 绘制多边形的更多相关文章

  1. 用线框模式绘制多边形 glPolygonMode

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_TRIANGLES);//开始以g_ViewMode模式绘制 glColor3ub(182. ...

  2. [WebGL入门]十四,绘制多边形

    注意:文章翻译http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外,鄙人webgl研究还不够深入.一些专业词语,假设翻译有误,欢迎大家 ...

  3. canvas绘制多边形

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. leaflet简单例子,绘制多边形

    var crs = L.CRS.EPSG900913; var map = L.map('map', { crs: crs, width: '100%', height: '100%', maxZoo ...

  5. 【Silverlight】Bing Maps学习系列(五):绘制多边形(Polygon)图形(转)

    [Silverlight]Bing Maps学习系列(五):绘制多边形(Polygon)图形 Bing Maps Silverlight Control支持用户自定义绘制多边形(Polygon)图形, ...

  6. 浅谈使用canvas绘制多边形

    本文主要使用坐标轴的使用来绘制多边形,点位则都是在y轴上寻找,这种方法能够更好的理解图形与修改. //id为html里canvas标签的属性id: //x,y为坐标轴的起始位置,因为canvas默认坐 ...

  7. JS实现鼠标点击爱心&绘制多边形&每日一言功能

    本篇文章主要介绍我的个人博客 程序猿刘川枫 中页面使用的美化功能(基于JS实现): 1.鼠标点击出现不同颜色爱心特效 2.页面浮动多边形跟随鼠标移动 3.每日一言功能 1.鼠标点击出现爱心特效 经常在 ...

  8. Unity动态构建mesh绘制多边形算法流程分析和实践

    前言 先说一下,写这篇博文的动机,原文的博主代码写的十分潇洒,以至于代码说明和注释都没有,最近恰逢看到,所以以此博文来分析其中的算法和流程 参考博文:https://blog.csdn.net/lin ...

  9. unity 绘制三角形

    哎 该学的还是要学 参考:http://www.narkii.com/club/thread-369573-1.html unity 顶点绘制三角形 脚本绘制; 其实filter和render就是进行 ...

随机推荐

  1. shell基础——字符串处理(转载)

    Shell的字符串处理   1 得到长度   %x="abcd"  #方法一      %expr length $x      4  # 方法二      %echo ${#x} ...

  2. Delphi通过GetFileVersionInfo和VerQueryValue等API函数取得详细EXE信息

    This has been described at About: http://delphi.about.com/cs/adptips2001/a/bltip0701_4.htmBasically, ...

  3. read write spinlock

    发一个自己基于 C++11 写的 read write spinlock,在 MinGW 4.8.2 (gcc 4.8 全面支持c++ 11,但由于gcc windows平台 libstdc++ 目前 ...

  4. 命令行解释器(shell)

    unix> ./hello hello world unix> ll 显示当前目录下文件信息. shell为命令行解释器,第一个单词可以是内置的外壳命令,也可以是一个可执行文件名.

  5. 关于SQLSERVER去掉如何重复值的记录

    这个一个在日常工作中所遇到的问题 在此记录一下 dt_user_pay_record表 ID userid time money 1 2 2014-3-2 2 2 2 2015-3-2 33 3 2 ...

  6. docker学习笔记(1)

    (1)Docker介绍 关于Docker的介绍,我就不列举出来了.到百度.谷歌搜索.非常多介绍文章.以下我给出官网的介绍:https://www.docker.com/whatisdocker/ (2 ...

  7. openfire研究之部署连接管理器(connection manager)

    http://blog.sina.com.cn/s/blog_7325f5150101bafh.html 一. Openfire Connection Manager 简介 Openfire Conn ...

  8. spark安装mysql与hive

    第一眼spark安装文件夹lib\spark-assembly-1.0.0-hadoop2.2.0.jar\org\apache\spark\sql下有没有hive文件夹,假设没有的话先下载支持hiv ...

  9. the first has precedence, perhaps you need a NameVirtualHost directive

    报错信息1: Starting httpd: [Fri May 19 11:49:42 2011] [warn] VirtualHost 127.0.0.1:80 overl aps with Vir ...

  10. 代码生成引擎之T4模版

    在学校三年.公司里呆了快一年了,作用ASP.NET开发的我,居然从来没听过T4模版,公司里也没有人使用,它就是这样不为世人所熟知,却又默默的奉献着!这...........tm还是我吗?什么时候会说这 ...