Unity中UGUI的 OnPopulateMesh函数与VertexHelper类

Graphics类

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

UGUI中与显示相关的控件,例如Image、Text、RawImage等都继承自MaskableGraphic类,MaskableGraphic类继承自Graphic类

控件在画面中的形状、颜色、法线等信息都是由Graphics类中的OnPopulateMesh函数所控制
每当改变了顶点或者纹理后,会调用OnPopulateMesh函数
其中需要的输入参数VertexHelper是一个顶点辅助类,保存着生成Mesh的基本信息


绘制UGUI还可以通过Mesh,但一般不怎么使用
就跟一个3D物体能显示出来因为它的MeshRender和MeshFilter,2D Sprite能显示出来因为它的SpriteRender,UGUI元素也是一样,每个UI元素都有一个CanvasRender组件

    CanvasRenderer render;Vector3[] vertices;int[] triangles;void Update(){Mesh mesh = new Mesh();mesh.vertices = vertices;mesh.triangles = triangles;render = GetComponent<CanvasRenderer>();render.SetMesh(mesh);}

鼠标画线功能

 使用UGUI中的重写了 OnPopulateMesh( VertexHelper vh )  这个方法,然后用来绘制,改一下,可以用来实现鼠标画线的功能。详细参考:

Unity 画线OnPopulateMesh函数VertexHelper_Peter_Gao_的博客-CSDN博客


 

 VertexHelper的类结构

OnPopulateMesh( VertexHelper vh ) 函数中 UI元素的顶点数据会填充这个参数 VertexHelper数据结构,我们可以修改这个数据结构里面的数据从而影响到顶点的一些属性。VertexHelper类的属性和方法:

在这里插入图片描述

VertexHelper类的绘制基本图形方法


AddVert:添加顶点(第一个添加的顶点索引为0,第二个添加的顶点为1,依次.....)
AddTriangle:绘制三角形(GPU绘制时会按照输入的顶点下标的顺序绘制一个三角形)
currentIndexCount:VertexHelper结构中有几个顶点索引(重合的顶点被计为2个顶点,例如一个三角形最少有3个顶点,一个正方形最少有6个顶点)
currentVertCount:VertexHelper结构中有几个顶点(AddVert添加了几个顶点就有几个)
PopulateUIVertex:获取某个索引的顶点数据
SetUIVertex:设置某个索引的顶点数据
AddUIVertexQuad:把AddVert和AddTriangle封装到一个函数中
AddUIVertexStream:把AddVert和AddTriangle封装到一个函数中

绘制三角形

我们用AddVert和AddTriangle绘制一个三角形
在这里插入图片描述
我们创建一个脚本TestVertexHelper.cs并继承Graphic,因为OnPopulateMesh函数定义在Graphic中

using UnityEngine.UI;
using UnityEngine;public class Test : Graphic
{protected override void OnPopulateMesh(VertexHelper vh){base.OnPopulateMesh(vh);vh.Clear();vh.AddVert(new Vector3(0, 0), Color.black, Vector2.zero);vh.AddVert(new Vector3(0, 100), Color.black, Vector2.zero);vh.AddVert(new Vector3(100, 0), Color.black, Vector2.zero);vh.AddTriangle(0, 1, 2);}
}

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

绘制正方形

我们用AddVert和AddTriangle绘制一个正方形

在这里插入图片描述

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);}
}

我们首先用AddVert添加了四个顶点,顶点的顺序如图;然后用AddTriangle添加了两个三角形,其中vh.AddTriangle(0, 1, 2)表示用顶点0,1,2来绘制一个三角形,vh.AddTriangle(2, 3, 0)表示用顶点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函数

返回指定索引的顶点数据,返回的顶点数据会填充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函数

设置一个顶点的数据

我们上面把第三个顶点的颜色设置为了黑色(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)函数

增加一个长方形

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 verts, List indices);

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

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

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

public class TestVertexHelper : Graphic
{
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
List verts = new List();

    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 verts)函数

这个方法向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 stream)函数

获取当前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);}}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/18789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构--单链表

前言 上一章&#xff0c;我们讲了数据结构--动态顺序表&#xff0c;我们会发现有以下问题&#xff1a; 1.当我们要头部或者插入或删除时&#xff0c;都需要进行位置挪动&#xff0c;腾出某一个位置&#xff0c;时间复杂度为0(N)&#xff1b; 2.增容需要申请新空间&#xff0c;…

SpringBoot2.2.0.RELEASE整合Elasticsearch6.8.3

SpringBoot2.2.0.RELEASE整合Elasticsearch6.8.3 SpringBoot是2.2.0.RELEASE&#xff0c;elasticsearch是6.8.3 使用依赖spring-boot-starter-data-elasticsearch 使用ElasticSearchRepository操作 1、导入依赖 <?xml version"1.0" encoding"UTF-8&quo…

VMware Linux Centos 配置网络并设置为静态ip

在root用户下进行以下操作 1. 查看子网ip和网关 &#xff08;1&#xff09;进入虚拟网络编辑器 &#xff08;2&#xff09;进入NAT设置 &#xff08;3&#xff09;记录子网IP和子网掩码 2. 修改网络配置文件 &#xff08;1&#xff09;cd到网络配置文件路径下 [rootlo…

工欲善其事必先利其器,IT工作电脑更要维护好

目录 一&#xff1a;电脑的组成 二&#xff1a;维护措施 三&#xff1a;助力记忆 一&#xff1a;电脑的组成 当谈到电脑主机时&#xff0c;我们通常指的是电脑的中央处理器(CPU)、内存、主板、电源、硬盘、显卡、声卡、网卡等核心部件组成的整体。这些部件共同协作&#xff…

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法

Kafka系列之:记录一次Kafka Topic分区扩容,但是下游flink消费者没有自动消费新的分区的解决方法 一、背景二、解决方法三、实现自动发现新的分区一、背景 生产环境Kafka集群压力大,Topic读写压力大,消费的lag比较大,因此通过扩容Topic的分区,增大Topic的读写性能理论上下…

力扣 62. 不同路径

题目来源&#xff1a;https://leetcode.cn/problems/unique-paths/ C题解1&#xff1a;动态规划。声明二维数组。 确定dp数组&#xff08;dp table&#xff09;以及下标的含义。dp[i][j] &#xff1a;表示从&#xff08;0 &#xff0c;0&#xff09;出发&#xff0c;到(i, j) …

Kafka-Broker工作流程

kafka集群在启动时&#xff0c;会将每个broker节点注册到zookeeper中&#xff0c;每个broker节点都有一个controller&#xff0c;哪个controller先在zookeeper中注册&#xff0c;哪个controller就负责监听brokers节点变化&#xff0c;当有分区的leader挂掉时&#xff0c;contro…

一行命令删除tag为<none>的镜像

sudo docker images | grep none | awk {print $3;} | xargs sudo docker rmi

DBeaver开源数据库管理工具发布23.1.3版本

导读DBeaver开源数据库管理软件近日发布了v23.1.3版本,该版本在空间数据查看器、数据传输、数据编辑器等多个模块进行了优化,提升了软件的可用性和兼容性。 具体来看,空间数据查看器新增了地图对象标记和曲线渲染支持,也实现了坐标复制等功能。数据传输模块增强了XLSX文件导入和…

【JVM】什么是双亲委派机制

文章目录 1、类加载机制2、双亲委派模型2.1、介绍2.2、为什么需要双亲委派2.3、源码解析 3、破坏双亲委派3.1、介绍3.2、破坏实现3.3、破坏双亲委派的例子 4、线程上下文类加载器 1、类加载机制 类加载阶段分为加载、连接、初始化三个阶段&#xff0c;而加载阶段需要通过类的全…

Vue2(初识vue)

目录 一&#xff0c;Vue2简介1.1&#xff0c;什么是vue1.2&#xff0c;初始vue1.3&#xff0c;搭建vue环境1.4&#xff0c;第一个hello world 二&#xff0c;基础知识2.1 指令2.2-1 指令v-text2.2-2 指令v-html2.2-3 指令v-if2.2-4 指令v-else2.2-5 指令v-show2.2-6 v-if指令与…

深入学习 Redis - 渐进式遍历 scan 命令、数据库管理命令

目录 前言 一、scan 命令 二、数据库管理命令 select dbsize flushdb / flushall 前言 之前我们所了解到的 keys * 是一次性把整个 redis 中所有的 key 都获取到&#xff0c;但是整个操作比较危险&#xff0c;可能会一下子的都太多的 key&#xff0c;阻塞 redis 服务器. …

centos系统离线安装k8s v1.23.9最后一个版本并部署服务,docker支持的最后一个版本

注意&#xff1a;我这里的离线安装包是V1.23.9. K8S v1.23.9离线安装包下载&#xff1a; 链接&#xff1a;https://download.csdn.net/download/qq_14910065/88143546 这里包括离线安装所有的镜像&#xff0c;kubeadm&#xff0c;kubelet 和kubectl&#xff0c;calico.yaml&am…

linux系统共享文件夹的创建和使用(VMware )

虚拟机设置共享文件夹 点击设置 点击选项 选择共享文件夹 随便添加一个电脑上的文件夹 虚拟机内打开共享文件夹 打开根目录 打开mnt文件夹 继续点击 最终得到共享文件夹

一文讲清多线程与多线程同步

1 多线程 1.1 线程的概念 十多年前&#xff0c;主流观点主张在可能的情况下优先选择多进程而非多线程&#xff0c;如今&#xff0c;多线程编程已经成为编程领域的事实标准。多线程技术在很大程度上改善了程序的性能和响应能力&#xff0c;使其能够更加高效地利用系统资源&…

【读书笔记】CHAPTER 1: SCALE FROM ZERO TO MILLIONS OF USERS

如果你有一定工作经验&#xff0c;或者开发项目基础&#xff0c;就看这个图就可以。 一个“从零扩展到数百万用户”系统&#xff0c;基本由上述部分组成&#xff1a; web、app&#xff1a;触达用户的设备&#xff08;页面&#xff09; DNS&#xff1a;用户看到的都是域名(ww…

count(列名) ,count(1)与count(*) 有何区别?

Mysql版本&#xff1a;8.0.26 可视化客户端&#xff1a;sql yog 文章目录 一、Mysql之count函数简介二、count(列名) &#xff0c;count(常量)与count(*) 有何区别&#xff1f;2.1 统计字段上的区别2.2 执行效率上的区别 一、Mysql之count函数简介 &#x1f449;表达式 COUNT(…

Centos7 上安装 redis-dump 和redis-load 命令

一、安装rvm 1、安装GPG keys gpg2 --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDBcurl -sSL http://rvm.io/mpapis.asc | gpg2 --import - curl -sSL http://rvm.io/pkuczynski.asc | g…

如何在项目需求与技术方案未确定的情况下掌控上线时间?

需求不明确与技术方案未确定的挑战 在任何项目管理过程中&#xff0c;需求和技术方案是两个核心环节。理想情况下&#xff0c;我们希望在项目开始阶段就有清晰明确的需求和经过深思熟虑的技术方案。然而&#xff0c;现实中的项目管理往往并不如此理想。 项目需求的重要性 需求…

谷粒商城第七天-商品服务之分类管理下的删除、新增以及修改商品分类

目录 一、总述 1.1 前端思路 1.2 后端思路 二、前端部分 2.1 删除功能 2.2 新增功能 2.3 修改功能 三、后端部分 3.1 删除接口 3.2 新增接口 3.3 修改接口 四、总结 一、总述 1.1 前端思路 删除和新增以及修改的前端无非就是点击按钮&#xff0c;就向后端发送请求…