Unity 顶点基础 + OnPopulateMesh

43 篇文章 1 订阅
26 篇文章 3 订阅

转自:

https://www.cnblogs.com/lyh916/p/9162463.html

https://blog.csdn.net/jk823394954/article/details/53870779

一.图形绘制

1.绘制三角形

using UnityEngine;
using UnityEngine.UI;

public class TestMesh : BaseMeshEffect {

    public override void ModifyMesh(VertexHelper vh)
    {
        vh.Clear();
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddTriangle(0, 1, 2);
    }
}

2.绘制正方形(绘制两个三角形)

using UnityEngine;
using UnityEngine.UI;

public class TestMesh : BaseMeshEffect {

    public override void ModifyMesh(VertexHelper vh)
    {
        vh.Clear();
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddVert(new Vector3(100, 0), Color.blue, Vector2.zero);
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);
    }
}

3.绘制正方形(绘制一个正方形)

using UnityEngine;
using UnityEngine.UI;

public class TestMesh : BaseMeshEffect {

    public override void ModifyMesh(VertexHelper vh)
    {
        vh.Clear();
        UIVertex[] verts = new UIVertex[4];

        verts[0].position = new Vector3(0, 0);
        verts[0].color = Color.red;
        verts[0].uv0 = Vector2.zero;

        verts[1].position = new Vector3(0, 100);
        verts[1].color = Color.green;
        verts[1].uv0 = Vector2.zero;

        verts[2].position = new Vector3(100, 100);
        verts[2].color = Color.black;
        verts[2].uv0 = Vector2.zero;

        verts[3].position = new Vector3(100, 0);
        verts[3].color = Color.blue;
        verts[3].uv0 = Vector2.zero;

        vh.AddUIVertexQuad(verts);
    }
}

二.相关api

using UnityEngine;
using UnityEngine.UI;

public class TestMesh : BaseMeshEffect {

    public override void ModifyMesh(VertexHelper vh)
    {
        vh.Clear();
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddVert(new Vector3(100, 0), Color.blue, Vector2.zero);
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);

        //顶点有4个,索引有6个
        Debug.Log(vh.currentIndexCount);
        Debug.Log(vh.currentVertCount);

        //PopulateUIVertex,返回顶点数据。当前取值范围:0-3
        UIVertex vertex = new UIVertex();
        vh.PopulateUIVertex(ref vertex, 0);
        Debug.Log(vertex.color);
        vh.PopulateUIVertex(ref vertex, 3);
        Debug.Log(vertex.color);

        //SetUIVertex,设置顶点数据
        vertex.color = Color.yellow;
        vh.SetUIVertex(vertex, 3);
    }
}

输出:

Stream流批量操作:

1.AddUIVertexStream,批量添加顶点

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestMesh : BaseMeshEffect {

    public override void ModifyMesh(VertexHelper vh)
    {
        vh.Clear();
        List<UIVertex> verts = new List<UIVertex>();

        UIVertex vert0 = new UIVertex();
        vert0.position = new Vector3(0, 0);
        vert0.color = Color.red;
        vert0.uv0 = Vector2.zero;
        verts.Add(vert0);

        UIVertex vert1 = new UIVertex();
        vert1.position = new Vector3(0, 100);
        vert1.color = Color.green;
        vert1.uv0 = Vector2.zero;
        verts.Add(vert1);

        UIVertex vert2 = new UIVertex();
        vert2.position = new Vector3(100, 100);
        vert2.color = Color.black;
        vert2.uv0 = Vector2.zero;
        verts.Add(vert2);

        UIVertex vert3 = new UIVertex();
        vert3.position = new Vector3(100, 0);
        vert3.color = Color.blue;
        vert3.uv0 = Vector2.zero;
        verts.Add(vert3);

        List<int> indices = new List<int>() { 0, 1, 2, 2, 3, 0 };
        vh.AddUIVertexStream(verts, indices);
    }
}

2.AddUIVertexTriangleStream,批量添加三角形顶点,长度必须是3的倍数

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestMesh : BaseMeshEffect {

    public override void ModifyMesh(VertexHelper vh)
    {
        vh.Clear();
        List<UIVertex> verts = new List<UIVertex>();

        UIVertex vert0 = new UIVertex();
        vert0.position = new Vector3(0, 0);
        vert0.color = Color.red;
        vert0.uv0 = Vector2.zero;
        verts.Add(vert0);

        UIVertex vert1 = new UIVertex();
        vert1.position = new Vector3(0, 100);
        vert1.color = Color.green;
        vert1.uv0 = Vector2.zero;
        verts.Add(vert1);

        UIVertex vert2 = new UIVertex();
        vert2.position = new Vector3(100, 100);
        vert2.color = Color.black;
        vert2.uv0 = Vector2.zero;
        verts.Add(vert2);

        vh.AddUIVertexTriangleStream(verts);
    }
}

3.GetUIVertexStream,获取所有顶点数据

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestMesh : BaseMeshEffect {

    public override void ModifyMesh(VertexHelper vh)
    {
        vh.Clear();
     
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddTriangle(0, 1, 2);

        List<UIVertex> stream = new List<UIVertex>();
        vh.GetUIVertexStream(stream);
        foreach (UIVertex v in stream)
        {
            Debug.Log(v.color);
        }
    }
}

三、OnPopulateMesh

1、OnPopulateMesh函数:当一个UI元素生成顶点数据时会调用OnPopulateMesh(VertexHelper vh)函数,我们可以在这个函数中修改顶点的数据或者获取顶点的数据。

2、VertexHelper结构:UI元素的顶点数据会填充这个数据结构,我们可以修改这个数据结构里面的数据从而影响到顶点的一些属性。

3、在Unity文档中有如下的属性和方法

AddVert:添加一个顶点到VertexHelper缓存中

AddTriangle:添加一个三角形到VertexHelper缓存中

例子:

①用AddVert和AddTriangle绘制一个三角形

创建一个脚本TestVertexHelper.cs并继承Graphic,因为OnPopulateMesh函数定义在Graphic中

首先用AddVert添加了三个顶点,三个顶点的关系如上图
然后用AddTriangle添加三角形,参数是三角形顶点的索引
GPU在绘制的时候会按照 顶点0->顶点1->顶点2 来绘制一个三角形

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
 
        vh.AddTriangle(0, 1, 2);
    }
}

②用AddVert和AddTriangle绘制一个正方形

首先用AddVert添加了四个顶点,顶点的顺序如图
然后用AddTriangle添加了两个三角形
vh.AddTriangle(0, 1, 2)表示用 顶点0,1,2 来绘制一个三角形
vh.AddTriangle(2, 3, 0)表示用 顶点2,3,0 来绘制一个三角形

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        //添加四个顶点
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddVert(new Vector3(100, 0), Color.blue, Vector2.zero);
        //添加两个三角形
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);
    }
}

属性currentIndexCount 和currentVertCount

currentVertCount:VertexHelper结构中有几个顶点

currentIndexCount:VertexHelper结构中有几个顶点索引

来打印一下刚才绘制的正方形的信息

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        //添加四个顶点
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddVert(new Vector3(100, 0), Color.blue, Vector2.zero);
        //添加两个三角形
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);
 
        Debug.Log("currentIndexCount " + vh.currentIndexCount);
        Debug.Log("currentVertCount " + vh.currentVertCount);
    }
}

可以看到顶点索引有四个,顶点有六个。顶点索引有四个(0,1,2,3)这个好理解,但是我们用AddVert添加了四个顶点,这里怎么显示有六个呢?因为unity会把三角形交界处的顶点分成两个。即三角形(0,1,2)和三角形(2,3,0)重合的顶点0,2会被分成两个顶点来处理。

PopulateUIVertex函数

PopulateUIVertex:返回指定索引的顶点数据,返回的顶点数据会填充UIVertex数据结构

例子:

使用PopulateUIVertex函数获取索引为2的顶点数据,然后打印出来

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        //添加四个顶点
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddVert(new Vector3(100, 0), Color.blue, Vector2.zero);
        //添加两个三角形
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);
 
        UIVertex vertex = new UIVertex();
        vh.PopulateUIVertex(ref vertex, 2);
        Debug.Log("color " + vertex.color + " position " + vertex.position + " uv0 " + vertex.uv0);
    }
}

看到这个数据,和我们设置的第三个顶点的数据是一样的

SetUIVertex函数

SetUIVertex:设置一个顶点的数据

例子:把上面第三个顶点的颜色设置为了黑色(vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);),我们通过SetUIVertex函数把第三个顶点(索引为2的顶点,索引从0开始)的三色设置为黄色

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        //添加四个顶点
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        vh.AddVert(new Vector3(100, 0), Color.blue, Vector2.zero);
        //添加两个三角形
        vh.AddTriangle(0, 1, 2);
        vh.AddTriangle(2, 3, 0);
 
        //得到第三个顶点(顶点索引为2,从0开始)的颜色
        UIVertex vertex = new UIVertex();
        vh.PopulateUIVertex(ref vertex, 2);
        //设置颜色为黄色
        vertex.color = Color.yellow;
        vh.SetUIVertex(vertex, 2);
    }
}

可以看到索引为2的顶点变成了黄色

 

AddUIVertexQuad(UIVertex[] verts)函数

AddUIVertexQuad:增加一个长方形

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        UIVertex[] verts = new UIVertex[4];
        verts[0].position = new Vector3(0, 0);
        verts[0].color = Color.red;
        verts[0].uv0 = Vector2.zero;
 
        verts[1].position = new Vector3(0, 100);
        verts[1].color = Color.green;
        verts[1].uv0 = Vector2.zero;
 
        verts[2].position = new Vector3(100, 100);
        verts[2].color = Color.black;
        verts[2].uv0 = Vector2.zero;
 
        verts[3].position = new Vector3(100, 0);
        verts[3].color = Color.blue;
        verts[3].uv0 = Vector2.zero;
 
        vh.AddUIVertexQuad(verts);
    }
}

可以看到这个方法和绘制两个三角形产生的效果是一样的

 

public void AddUIVertexStream(List<UIVertex> verts, List<int> indices)函数

AddUIVertexStream:向VertexHelper中批量增加顶点数据,第一个参数为顶点数据,第二个参数为构成图元的顶点索引目录

假如我们要绘制两个三角形,加入我们有两个三角形,顶点索引分别为(0,1,2),(2,3,0),那么我们的indices应该定义为

List<int> indices = new List<int>() { 0, 1, 2, 2, 3, 0 };

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        List<UIVertex> verts = new List<UIVertex>();
 
        UIVertex vert0 = new UIVertex();
        vert0.position = new Vector3(0, 0);
        vert0.color = Color.red;
        vert0.uv0 = Vector2.zero;
        verts.Add(vert0);
 
        UIVertex vert1 = new UIVertex();
        vert1.position = new Vector3(0, 100);
        vert1.color = Color.green;
        vert1.uv0 = Vector2.zero;
        verts.Add(vert1);
 
        UIVertex vert2 = new UIVertex();
        vert2.position = new Vector3(100, 100);
        vert2.color = Color.black;
        vert2.uv0 = Vector2.zero;
        verts.Add(vert2);
 
        UIVertex vert3 = new UIVertex();
        vert3.position = new Vector3(100, 0);
        vert3.color = Color.blue;
        vert3.uv0 = Vector2.zero;
        verts.Add(vert3);
 
        List<int> indices = new List<int>() { 0, 1, 2, 2, 3, 0 };
        vh.AddUIVertexStream(verts, indices);
    }
}

效果:

 void AddUIVertexTriangleStream(List<UIVertex> verts)函数

AddUIVertexTriangleStream:向VertexHelper中批量增加三角形顶点数据,参数的长度必须是三的倍数

public class TestVertexHelper : Graphic
{
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        List<UIVertex> verts = new List<UIVertex>();
 
        UIVertex vert0 = new UIVertex();
        vert0.position = new Vector3(0, 0);
        vert0.color = Color.red;
        vert0.uv0 = Vector2.zero;
        verts.Add(vert0);
 
        UIVertex vert1 = new UIVertex();
        vert1.position = new Vector3(0, 100);
        vert1.color = Color.green;
        vert1.uv0 = Vector2.zero;
        verts.Add(vert1);
 
        UIVertex vert2 = new UIVertex();
        vert2.position = new Vector3(100, 100);
        vert2.color = Color.black;
        vert2.uv0 = Vector2.zero;
        verts.Add(vert2);
 
        vh.AddUIVertexTriangleStream(verts);
    }
}

效果:

GetUIVertexStream(List<UIVertex> stream)函数

GetUIVertexStream:获取当前VertexHelper中的所有顶点的信息

public class TestVertexHelper : Graphic
{
 
    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();
        //添加三个顶点
        vh.AddVert(new Vector3(0, 0), Color.red, Vector2.zero);
        vh.AddVert(new Vector3(0, 100), Color.green, Vector2.zero);
        vh.AddVert(new Vector3(100, 100), Color.black, Vector2.zero);
        //添加三角形
        vh.AddTriangle(0, 1, 2);
        //得到所有顶点的信息
        List<UIVertex> stream = new List<UIVertex>();
        vh.GetUIVertexStream(stream);
        foreach (UIVertex v in stream) {
            Debug.Log("color " + v.color + " position " + v.position + " uv0 " + v.uv0);
        }
    }
}

可以看到输出日志的值和输入的顶点信息一样

 

 

 

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值