【转载】Unity3D研究院之与根据动态的两个轨迹点绘制面详解
大家应该知道3D世界中任何的面都是由三角形绘制完成的,因为任何无规则的集合图形都可以由三角形来组成。比如四边形,无论是正四边形还是无规则四边形都可以由两个三角形拼接而成。结合本文的标题大家仔细想想,如果需要绘制一个动态无规则面其实只需要得到动态的两个轨迹点即可,那么结合下面的图片大家仔细在想想。

暂时我们先忽略Z轴(这样在平面中看得更清楚),假设Z轴坐标都为0。假设游戏中有两个轨迹点在动态的增加与改变,最后将这两个点改变的轨迹拼接起来就是它们生成的面。如上图所示,第一个点的轨迹是“ 3,4,5,6,7” 第二个点的轨迹是“2,1,10,9,8” 。这两个点的长度是可变的,前提是他们两个的数量必需完全一样。接着,如下图所示,我们将这些点两两相连起来,目前一共形成了8个三角形面(可根据两个动态点的数量而确定整个网格面三角形面的数量)。最后我们将这8个三角形填充上同样的颜色,就可以实现一个完整的立体网格面。

原理很简单,就是这样的我相信大家看到这里大家都能明白,接着我们就学习如何使用代码来实现它。首先创建Unity工程,接着创建一个空的游戏对象,然后给该游戏对象绑定Mesh Filter组件 与 Mesh Renderer组件。
Mesh Filter组件:表示网格面,这个网格面是由我们使用代码将所有三角形拼接起来生成的面。
Mesh Renderer组件:表示表示网格的渲染,可设置一个渲染的材质,它包括贴图与颜色。
如下图所示,我说说里面比较重要的属性。Mesh Renderer中,Materials下拉列表中可设置网格模型的材质,此时我们设置了一个红色的材质。 Mesh Filter:目前为None,也不用再编辑器中为它赋值,因为这个网格模型我们会在代码中生成并且赋值。在下面就是方刚我们设置红色的材质资源,Shader中设置了贴图的属性,目前是GUI/ TextShader。它表示这个材质的渲染级别在GUI上,就是优先级是最一层的。举个例子无论在这个网格模型的前面绘制多少模型,它永远都会在最前面显示。就这个例子而言它的存在并不是必需的,其实Shader的选项还有很多,可透明、不可透明、镜面、反射等等,后期我会向大家详细道来。

OK,现在资源文件都已经准备完毕,下面我们学习如何来绘制一个三角形,从简单的开始。。把下面的代码绑定在摄像机对象当中。
void Start()
{
//得到MeshFilter对象,目前是空的。
MeshFilter meshFilter = (MeshFilter)GameObject.Find("face").GetComponent(typeof(MeshFilter));
//得到对应的网格对象
Mesh mesh = meshFilter.mesh;
//三角形顶点的坐标数组
Vector3[] vertices = ];
//三角形顶点ID数组
];
//三角形三个定点坐标,为了显示清楚忽略Z轴
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
//三角形绘制顶点的数组
triangles[] = ;
triangles[] = ;
triangles[] = ;
mesh.vertices = vertices;
mesh.triangles = triangles;
}
代码中有两个非常重要的概念,就是三角形顶点数组与坐标数组。先说说坐标数组,假设需要绘制一个四边形,此时三角形坐标数组的长度应当是4,它保存着四边形四个顶点的坐标。然后是顶点数组,四边形是由两个三角形组成,然而一个三角形是由3个顶点组成,两个三角形就应当是6个顶点组成,无论多少个三角形它们的结构都应当是以此类推。
注解1:这里是将模型的顶点数组与坐标数组赋值给网格模型,还记得刚刚在创建Mesh Filter时,当时没有在编辑器中给网格模型赋值,实际上代码走到这里就会重新为网格模型MeshFilter赋值,接着我们在代码中绘制的三角形就会显示在屏幕当中。
如图所示,三角形已经绘制在屏幕当中。
图中数组 0 1 2 表示该三角形的三个顶点的ID。这个ID对应代码中对应vertices数组索引顶点的坐标。也就是说(0,0,0)对应顶点0,(0,1,0)对应顶点1,(1,0,0)对应顶点2

下面我们修改一下代码,让屏幕中一共绘制4个三角形。
//网格模型顶点数量
;
void Start()
{
//得到MeshFilter对象,目前是空的。
MeshFilter meshFilter = (MeshFilter)GameObject.Find("face").GetComponent(typeof(MeshFilter));
//得到对应的网格对象
Mesh mesh = meshFilter.mesh;
//三角形顶点的坐标数组
Vector3[] vertices = new Vector3[VERTICES_COUNT];
//得到三角形的数量
;
//三角形顶点ID数组
];
//三角形三个定点坐标,为了显示清楚忽略Z轴
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
//三角形绘制顶点的数组
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
triangles[] = ;
//绘制三角形
mesh.vertices = vertices;
mesh.triangles = triangles;
}
已知模型的顶点数量,顶点数量减去2就是三角形的数量,三角形的数量在乘以3就是三角形顶点的数量。根据这个公式计算得知,上述代码中共绘制4个三角形,顶点坐标数组应当是6,顶点ID数组应当是12。多个三角形在顶点ID数组中排列方式比较特殊,大家需要仔细记录一下不然无法绘制出正确的三角形。如下图所示,由于我这边没有合适的3D坐标点,就用正三角形拼接出一个正四边形,这个四边形是由6个顶点4个小三角形组成 ,看到这里思路清晰的朋友应当明了无规则四边形的绘制原理和它完全一样。只需要传入适当的3D坐标点即可。

根据上面的逻辑,我们修改一下算法。假设三角形的顶点坐标为任意数量,我们需要更根据顶点坐标数量来计算对应顶点ID的数组内容。在for循环中start =0 与end =3的含义是绘制从顶点坐标数组中索引为0的顶点开始绘制到数组索引为3的顶点,也就说是这里从0到3绘制了3个三角形。
//网格模型顶点数量
;
void Start()
{
//得到MeshFilter对象,目前是空的。
MeshFilter meshFilter = (MeshFilter)GameObject.Find("face").GetComponent(typeof(MeshFilter));
//得到对应的网格对象
Mesh mesh = meshFilter.mesh;
//三角形顶点的坐标数组
Vector3[] vertices = new Vector3[VERTICES_COUNT];
//得到三角形的数量
;
//三角形顶点ID数组
];
//三角形三个定点坐标,为了显示清楚忽略Z轴
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
vertices[] = , , );
//绘制三角形
mesh.vertices = vertices;
//起始三角形顶点
;
//结束三角形的顶点
;
for (int i = start; i < end; i++)
{
; j < ; j++)
{
== )
{
triangles[ * i + j] = i + j;
}
else
{
triangles[ * i + j] = i + - j;
}
}
}
mesh.triangles = triangles;
}
如下图所示,根据上面的逻辑算法,共绘制了3个三角形,并且顶点坐标ID是由 0 到3 。 说到这里请大家仔细想想本文的标题内容,其实两个动态轨迹的点就是在维护triangles顶点坐标数组。triangles[0]、triangles[2]、triangles[4]……表示一个轨迹点的值,triangles[1]、triangles[3]、triangles[5]……就表示另一个轨迹点的值,最终将它们通过上面的算法将三角形面连接起来那么就是动态的两个点轨迹绘制面了。

Unity3D其实非常好玩,上手虽然很简单,但是想深入其实并没有那么容易,今天这篇文章的思路已经写完,如果还是没能明白的朋友请仔细揣摩三角形与四边形之间的却别,哇咔咔,已经不早了我也得睡觉了,明天还得上班 GOGOGOGOGO加油~希望我们大家可以共同学习,共同进步。
- 本文固定链接: http://www.xuanyusong.com/archives/780
- 转载请注明: 雨松MOMO 2012年05月06日 于 雨松MOMO程序研究院 发表
【转载】Unity3D研究院之与根据动态的两个轨迹点绘制面详解的更多相关文章
- 技巧:Linux 动态库与静态库制作及使用详解
技巧:Linux 动态库与静态库制作及使用详解 标准库的三种连接方式及静态库制作与使用方法 Linux 应用开发通常要考虑三个问题,即:1)在 Linux 应用程序开发过程中遇到过标准库链接在不同 L ...
- 转载文章-----Rational Rose2007(v7.0)下载地址、安装及激活详解教程(图)
转载地址:http://www.cnblogs.com/leaven/p/3718361.html 最近需要画uml图,之前用的是Rose 2003版的,由于好久没进去了,结果发现原来的激活又失效了, ...
- (转载)Unity3D研究院之使用 C#合成解析XML与JSON(四十一)
XML与JSON在开发中非常重要, 其实核心就是处理字符串.一个是XML的字符串一个是JSON的字符串,尤其是在处理网络请求的时候,肯定是要用的.另外现在JSON非常的流行,我写了一个简单的例子融合了 ...
- Unity3D研究院之游戏对象的访问绘制线与绘制面详解(十七)
一眨眼学习Unity3D 也有一段时间了,基本已经拿下了这套游戏引擎,回过头来想想以前写的RPG 游戏引擎,越来越发现以前写的就是垃圾.人果然是要不断学习与不断进步,好好学习,天天向上.哇咔咔- 加油 ...
- 转载:MySQL数据库INSERT、UPDATE、DELETE以及REPLACE语句的用法详解
转自:http://www.jb51.net/article/39199.htm 本篇文章是对MySQL数据库INSERT.UPDATE.DELETE以及REPLACE语句的用法进行了详细的分析介绍, ...
- 动态SQL各个标签作用以及注意事项详解
创建com.mybatis包,包含:UserMapper.xml和mybatis-config.xml UserMapper.xml代码: <?xml version="1.0&quo ...
- 转载:MySQL EXPLAIN 命令详解学习
转载自:https://blog.csdn.net/mchdba/article/details/9190771 MySQL EXPLAIN 命令详解 MySQL的EXPLAIN命令用于SQL语句的查 ...
- [转载]详解ssh端口转发(二)
关于使用ssh portforwarding来进行FQ的操作,网络上已经有很多很好的文章,我在这里只是画两个图解释一下. 首先要记住一件事情就是: SSH 端口转发自然需要 SSH 连接,而 SSH ...
- (转载)实例详解Android快速开发工具类总结
实例详解Android快速开发工具类总结 作者:LiJinlun 字体:[增加 减小] 类型:转载 时间:2016-01-24我要评论 这篇文章主要介绍了实例详解Android快速开发工具类总结的相关 ...
随机推荐
- 【BZOJ5212】[ZJOI2018] 历史(LCT大黑题)
点此看题面 大致题意: 给定一棵树每个节点\(Access\)的次数,求最大虚实链切换次数,带修改. 什么是\(Access\)? 推荐你先去学一学\(LCT\)吧. 初始化(不带修改的做法) 首先考 ...
- 有权并查集,Poj(1988)
题目链接:http://poj.org/problem?id=1988 题目大意: 有n个从1到n编号的箱子,将每个箱子当做一个栈,对这些箱子进行p次操作,每次操作分别为以下两种之一: 输入 M x ...
- (转)Fidder详解之get和post请求
https://www.cnblogs.com/langhuagungun/p/7737204.html 前言 本文会对Fidder这款工具的一些重要功 能,进行详细讲解,带大家进入Fidder的世界 ...
- 卷积神经网络CNN在自然语言处理的应用
摘要:CNN作为当今绝大多数计算机视觉系统的核心技术,在图像分类领域做出了巨大贡献.本文从计算机视觉的用例开始,介绍CNN及其在自然语言处理中的优势和发挥的作用. 当我们听到卷积神经网络(Convol ...
- 旧文备份:对象字典0x1005和0x1006的理解
SYNC不一定由主站产生,因此,产生SYNC的节点,0x1005对象的值一般是0x40000080,第30位为1表示本节点产生 SYNC,而本节点的0x1006对象就是产生同步周期值了;而接收SYNC ...
- lintcode_397_最长上升连续子序列
最长上升连续子序列 描述 笔记 数据 评测 给定一个整数数组(下标从 0 到 n-1, n 表示整个数组的规模),请找出该数组中的最长上升连续子序列.(最长上升连续子序列可以定义为从右到左或从左到 ...
- 用MySQL的optimizer_trace进行sql调优
在我们调优MySQL的SQL时候,通常使用三种工具进行查看sql执行的效率,explain.profile.optimizer_trace.前两个经常被人使用,由于第三个难度较大,大家使用的较少,下面 ...
- mongodb多个查询语句
db.getCollection('costitems').find({"created":{"$gte":ISODate("2019-01-02T0 ...
- python核心编程2 第八章 练习
8–2. 循环. 编写一个程序, 让用户输入三个数字: (f)rom, (t)o, 和 (i)ncrement . 以 i为步长, 从 f 计数到 t , 包括 f 和 t . 例如, 如果输入的是 ...
- LeetCode970. 强整数
问题:970. 强整数 用户通过次数0 用户尝试次数0 通过次数0 提交次数0 题目难度Easy 给定两个非负整数 x 和 y,如果某一整数等于 x^i + y^j,其中整数 i >= 0 且 ...