• 在Unity中使用UGUI修改Mesh绘制几何图形


    在商店看到这样一个例子,表示很有兴趣,他们说是用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>();

    2 vh.GetUIVertexStream(stream); 

    做法2:

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

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

    protected void OnPopulateMesh(UI.VertexHelper vh);

    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[
    0].position, color32, new Vector2(0f, 0f)); vh.AddVert(pos[1].position, color32, new Vector2(0f, 1f)); vh.AddVert(pos[2].position, color32, new Vector2(1f, 1f)); vh.AddVert(pos[3].position, color32, new Vector2(1f, 0f)); vh.AddVert(pos[4].position, color32, new Vector2(0.5f, 0f)); vh.AddTriangle(0, 1, 2); vh.AddTriangle(2, 3, 4); vh.AddTriangle(2, 4, 0); }

     

    注: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游戏选/创建角色界面中 职业能力图六角形

  • 相关阅读:
    Linux用户、用户组、文件权限设置
    spring,springMvc和mybatis整合配置
    spring,springMvc和hibernate整合
    spring与mybatis
    spring与Dbcp
    初识事物
    spring与Aop
    初识spring
    mysql 完整性约束
    mysql数据库的基本操作
  • 原文地址:https://www.cnblogs.com/jeason1997/p/5130413.html
Copyright © 2020-2023  润新知