在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的。我想,像这种可以随便变形的图形,我第一个就想到了网格变形。

做法1:

细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas Render'组件,就跟3D世界模型有'Mesh Render'以及2D Sprite

有’Sprite Render'一样,UGUI的UI元素也需要一个Render渲染出来,那么第一时间想到的就是修改Render的Mesh。

对Mesh操作不熟的可以看这篇文章

private CanvasRenderer render;

    void Update()
{
Mesh mesh = new Mesh();
mesh.SetVertices();      // 设置顶点,这里缩略没写出顶点数组
mesh.SetUVs();         // 同上
mesh.SetTriangles();      render = GetComponent<CanvasRenderer>();
render.SetMesh(mesh);
}

不过不知道为何,这种做法失败了,不知道是哪里出错,待我再研究下。

本来想直接获取render的mesh,然后在此mesh的基础上修改顶点的,可惜render并没有获取mesh的方法,或许是我还未发现。

刚刚试了下,又成功了,不过在Start里还是失败,我是放到Update里才成功的。

还有,获取顶点的方法:

1 OnPopulateMesh(UI.VertexHelper vh)

2 List<UIVertex> stream = new List<UIVertex>();

vh.GetUIVertexStream(stream);

做法2:

然后我想到UGUI是开源的,然后就跑去看源码,研究Image控件的实现原理,发现了Image是继承Graphic,

而Graphic里有OnPopulateMesh这个函数,查官方API:

protected void OnPopulateMesh(UI.VertexHelpervh);

Description

Callback function when a UI element needs to generate vertices.

Used by TextImage, and RawImage for example to generate vertices specific to their use case.

说的是当该控件(例如Text,Image,RawImage)需要改变顶点的时候,就会自动调用。

在传入的vh参数里修改顶点,三角形,UV等,同样可以达到修改mesh的目的。

不过该函数是只有在该Craphic组件需要修改的时候才会调用,比如你修改Image的大小,或者它加载的时候才会。

这样就导致我们没法及时看到我们对mesh的修改,比如用是将一张Image的四个角分别用四个对象表示,这四个对象的

移动,会让这种Image发生形变。但是没法及时更新就没办法了。

还好有SetNativeSize()这个方法,其实跟刷新差不多。

注:新发现,UGUI采用脏标记系统,只要控件被标记为“脏”状态,就会强制刷新一遍,在每次改变了顶点或者纹理后,调用SetVerticesDirty() 或 SetMaterialDirty()即可。

上代码:

// 自己手动刷新

void Update()
 {

  //SetNativeSize();

  SetVerticesDirty();
 }

protected override void OnPopulateMesh(VertexHelper vh)
{
Color32 color32 = color;
vh.Clear();
     // 这里我用5对GameObject的坐标来与该Image对象的五个顶点绑定起来
     // AddVert的最后一个参数是UV值
vh.AddVert(pos[].position, color32, new Vector2(0f, 0f));
vh.AddVert(pos[].position, color32, new Vector2(0f, 1f));
vh.AddVert(pos[].position, color32, new Vector2(1f, 1f));
vh.AddVert(pos[].position, color32, new Vector2(1f, 0f));
vh.AddVert(pos[].position, color32, new Vector2(0.5f, 0f)); vh.AddTriangle(, , );
vh.AddTriangle(, , );
vh.AddTriangle(, , );
}

注:Unity4.6的UGUI, 并不是用OnPopulateMesh来改变顶点,而是用OnFillVBO,用法基本相同,不同的是,4.6的UI的mesh是基于Quad而不是三角形,因此不用像上面那样设置完

顶点后,还需要设置三角形。但注意的是,Quad跟三角形不同的地方就是,它是由4个顶点组成的,因此设置的顶点数必须是4的倍数。设置Quad的时候,只需要4个一组的设置面片即可。

相比较三角形,Quad的概念容易理解,但是顶点的利用率大大降低,比如上面的5边形,用三角形只需要5个顶点,但用Quad则需要8个顶点。

做法3:

想起我之前为了让Text实现渐变效果写的一个扩展方法,就是创建一个组件脚本,这个组件继承BaseMeshEffect,

然后在里面覆写ModifyMesh(Mesh mesh)方法,在该方法内部实现修改mesh即可。

该文章里的第6点

最新的5.3版已经将该方法改成ModifyMesh(VertexHelper vh)(又TM改,我印象中这是第三次改了)

作用以及写法几乎与第二点一样,只是不用继承Graphic组件,这样可以实现比较好的扩展性。把效果做成Effect,

然后所有Graphic组件都可以通过添加该组件来实现扩展。

参考文章:

在Unity中使用uGUI绘制自定义图形(饼状图 雷达图)

Unity游戏选/创建角色界面中 职业能力图六角形

在Unity中使用UGUI修改Mesh绘制几何图形的更多相关文章

  1. 关于Unity中的UGUI优化,你可能遇到这些问题

    https://blog.uwa4d.com/archives/QA_UGUI-1.html 关于Unity中的UGUI优化,你可能遇到这些问题 作者:admin / 时间:2016年11月08日 / ...

  2. unity中的UGUI一些组件的使用

    一.Toggle Group(Script) LeftButtons上添加Toggle Group组件,属性Allow Switch Off打对勾,代表它的所有子物体上带有Toggle组件的属性Is ...

  3. unity 中的UGUI 屏蔽鼠标穿透

    void Update() { if(IsTouchedUI()) { Debug.Log("当前触摸在UI上"); } else { Debug.Log("当前没有触摸 ...

  4. 关于Unity 中对UGUI制作任务系统的编程

    版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...

  5. Unity中2D和UGUI图集的理解与使用

    图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢? ...

  6. 关于Unity中的NGUI和UGUI

    一.用Unity开发2D游戏,有三套关系 1.GUI:Unity本身自带的GUI 2.NGUI:以前在Unity中广泛来做2D的,是第三方的包,需要安装 3.UGUI:Unity5.X后(其实是Uni ...

  7. Unity中动态创建Mesh

    什么是Mesh? Mesh是指的模型的网格,3D模型是由多边形拼接而成,而多边形实际上又是由多个三角形拼接而成的.即一个3D模型的表面其实是由多个彼此相连的三角面构成.三维空间中,构成这些三角形的点和 ...

  8. Unity中Mesh分解与边缘高亮加上深度检测

    一个比较简单的需求,不过遇到些坑,记录下. 房间有多个模型,每个模型可能多个SubMesh,点击后,需要能具体到是那个SubMesh,并且在这个SubMesh上显示边缘高光,以及能个性这单个SubMe ...

  9. Mesh绘制雷达图(UGUI)

    参考资料:http://www.cnblogs.com/jeason1997/p/5130413.html ** 描述:雷达图 刷新 radarDate.SetVerticesDirty(); usi ...

随机推荐

  1. windows10的第一天使用总结

    一.快速开机设置 我的电脑配置如图,装有VS2015 2010 OFFICE等常用开发工具,在线升级后开机速度并没有明显提升. 1.保证windows font cache service服务启动,3 ...

  2. WordPress + Nginx +PHP+MySQL

    Windows下配置Nginx+php环境 1)php的安装与配置. 直接解压下载好的php包,到D盘wnmp目录(D:\wnmp),这里把解压出来的文件夹重命名成php5.进入文件夹修改php.in ...

  3. 重叠div鼠标经过事件

    两个div重叠了,但是下面的div有鼠标移入移出事件,发现当鼠标移入或者移出时事件会执行两次,尝试了在上层div阻止事件,判断div所在位置……,后来发现只要一个css属性即可解决该问题,在上层div ...

  4. ubuntu 14.04 配置tomacat8

    自己在虚拟机总安装tomcat8,主机访问,记下步骤方便以后查看. 1.将tomcat8安装包移动到/usr/local目录中(个人喜欢把自己安装的软件放到/usr/local文件夹中) 2.解压缩, ...

  5. Nginx深入详解之多进程网络模型

    一.进程模型        Nginx之所以为广大码农喜爱,除了其高性能外,还有其优雅的系统架构.与Memcached的经典多线程模型相比,Nginx是经典的多进程模型.Nginx启动后以daemon ...

  6. C#之发送邮件【模板】+【封装】ZJ版

    PS: 为了弥补上篇博客的不足,正好周六闲着没事.所以进行优化下,来个终结版 功能实现:模板发送+自指定邮箱发送+解耦 总体预览如下: 各代码如下:(代码略多,所以都折叠了) 前台; @{ Layou ...

  7. jq.validate 自定义验证两个日期

    jq.validate 自定义验证两个日期 首先定义有一个表单,date1和date2是属于表单的元素,若date1大于date2,返回false:若date1<date2,返回true.使用j ...

  8. 协程--gevent模块(单线程高并发)

    先恶补一下知识点,上节回顾 上下文切换:当CPU从执行一个线程切换到执行另外一个线程的时候,它需要先存储当前线程的本地的数据,程序指针等,然后载入另一个线程的本地数据,程序指针等,最后才开始执行.这种 ...

  9. 反序列化漏洞问题研究之php篇

    php的反序列化反序列化漏洞又称php对象注入(php Object Injection)产生的问题主要分以下两类: 将传来的序列化数据直接unserilize,造成魔幻函数的执行.这种情况在一般的应 ...

  10. vim编辑强制退出

    quit!命令可以进行强制退出 在修改文件时注意他的权限, ls -l:查看当前目录下的所有文件的详细信息