Unity---------Mesh理解
-
Mesh顾名思义“网格”,Unity3D里面所有的模型都是由Mesh组成的,UI也不例外。
例如下图,模型上的一个个小网格就是Mesh,这些Mesh有不同的三维顶点(Vector3),共同组成了一个3D模型。
Unity3D中Mesh的基本单位是三角形,学习应该由浅入深,所以今天我们就从最基本最简单的等腰三角形开始画起。
本文作者尚为初学者,如有理解不到位的地方,欢迎指正。
首先我们新建一个名为TestTriangle的CSharp脚本,然后打开TestTriangle,我们开始编写代码。
- using UnityEngine;
- using System.Collections;
- /* ==============================================================================
- * 功能描述:创建三角形Mesh
- * 创 建 者:Eci
- * 创建日期:2016/09/04
- * ==============================================================================*/
- [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
- public class TestTriangle : MonoBehaviour {
- public float sideLength = 2;
- public float angleDegree = 100;
- private MeshFilter meshFilter;
- [ExecuteInEditMode]
- private void Awake()
- {
- meshFilter = GetComponent<MeshFilter>();
- meshFilter.mesh = Create (sideLength, angleDegree);
- }
- private void Update()
- {
- }
- private Mesh Create(float sideLength, float angleDegree)
- {
- Mesh mesh = new Mesh();
- Vector3[] vertices = new Vector3[3];
- float angle = Mathf.Deg2Rad * angleDegree;
- float halfAngle = angle / 2;
- vertices [0] = Vector3.zero;
- float cosA = Mathf.Cos (halfAngle);
- float sinA = Mathf.Sin (halfAngle);
- vertices [1] = new Vector3 (cosA * sideLength, 0, sinA * sideLength);
- vertices [2] = new Vector3 (cosA * sideLength, 0, -sinA * sideLength);
- int[] triangles = new int[3];
- triangles [0] = 0;
- triangles [1] = 1;
- triangles [2] = 2;
- mesh.vertices = vertices;
- mesh.triangles = triangles;
- Vector2[] uvs = new Vector2[vertices.Length];
- for (int i = 0; i < uvs.Length; i++)
- {
- uvs[i] = Vector2.zero;
- }
- mesh.uv = uvs;
- return mesh;
- }
- }
RequireComponent这一行,表示我们需要MeshRenderer和MeshFilter这两个组件,当我们将TestTriangle的代码挂在GameObject上的时候,会自动添加这两个组件。而我们要移除MeshRenderer或MeshFilter的时候,编辑器就会提示不能移除。
然后我们给出了两个公开变量,sideLength边长和angleDegree角度,因为我们这里要画的是等腰三角形,这代表的是等腰边长和等腰边长的夹角。
ExecuteInEditMode表示会在编辑器模式下运行。
Awake里,我们获取了MeshFilter并为它创建了Mesh。
Create方法里面,我们看到,先后为新建的Mesh创建了vertices(定点),triangles(三角形),uv(纹理坐标)。
vertices很简单,就是计算三角形三个顶点的坐标,因为是个二维图形,所以y坐标都为零。
triangles里保存的是vertices的下标。
uv暂时我们用不到,所以全部设为零。在后面文章中我们会介绍uv的用法。
最后返回mesh。
在编辑器里,点击运行,我们就可以看到一个紫色(因为没有材质)的三角形。
但是只能在运行的时候才看得到这个三角形,编辑器里看不到怎么办?添加下面这段代码:
- void OnDrawGizmos()
- {
- Gizmos.color = Color.gray;
- DrawMesh();
- }
- void OnDrawGizmosSelected()
- {
- Gizmos.color = Color.green;
- DrawMesh();
- }
- private void DrawMesh()
- {
- Mesh mesh = Create(sideLength, angleDegree);
- int[] tris = mesh.triangles;
- Gizmos.DrawLine(mesh.vertices[tris[0]], mesh.vertices[tris[1]]);
- Gizmos.DrawLine(mesh.vertices[tris[0]], mesh.vertices[tris[2]]);
- Gizmos.DrawLine(mesh.vertices[tris[1]], mesh.vertices[tris[2]]);
- }
关于OnDrawGizmos和OnDrawGizmosSelected可以参考下面这个链接:
http://www.ceeger.com/Script/Gizmos/Gizmos.html简单来讲就是在编辑器模式下,绘制辅助线框。
这样一个简单的等腰三角形Mesh的绘制就完成了。什么?你不满意?我们稍微整理一下代码:
- using UnityEngine;
- using System.Collections;
- /* ==============================================================================
- * 功能描述:创建三角形Mesh
- * 创 建 者:Eci
- * 创建日期:2016/09/04
- * ==============================================================================*/
- [RequireComponent(typeof(MeshRenderer), typeof(MeshFilter))]
- public class TestTriangle : MonoBehaviour {
- public float sideLength = 2;
- public float angleDegree = 100;
- private static readonly int ANGLE_DEGREE_PRECISION = 1000;
- private static readonly int SIDE_LENGTH_PRECISION = 1000;
- private MeshFilter meshFilter;
- private TriangleMeshCreator creator = new TriangleMeshCreator();
- [ExecuteInEditMode]
- private void Awake()
- {
- meshFilter = GetComponent<MeshFilter>();
- }
- private void Update()
- {
- meshFilter.mesh = creator.CreateMesh(sideLength, angleDegree);
- }
- void OnDrawGizmos()
- {
- Gizmos.color = Color.gray;
- DrawMesh();
- }
- void OnDrawGizmosSelected()
- {
- Gizmos.color = Color.green;
- DrawMesh();
- }
- private void DrawMesh()
- {
- Mesh mesh = creator.CreateMesh(sideLength, angleDegree);
- int[] tris = mesh.triangles;
- Gizmos.DrawLine(transformToWorld(mesh.vertices[tris[0]]), transformToWorld(mesh.vertices[tris[1]]));
- Gizmos.DrawLine(transformToWorld(mesh.vertices[tris[0]]), transformToWorld(mesh.vertices[tris[2]]));
- Gizmos.DrawLine(transformToWorld(mesh.vertices[tris[1]]), transformToWorld(mesh.vertices[tris[2]]));
- }
- private Vector3 transformToWorld(Vector3 src)
- {
- return transform.TransformPoint(src);
- }
- private class TriangleMeshCreator
- {
- private float _sideLength;
- private float _angleDegree;
- private Mesh _cacheMesh ;
- public Mesh CreateMesh(float sideLength, float angleDegree)
- {
- if (checkDiff(sideLength, angleDegree))
- {
- Mesh newMesh = Create(sideLength, angleDegree);
- if (newMesh != null)
- {
- _cacheMesh = newMesh;
- this._sideLength = sideLength;
- this._angleDegree = angleDegree;
- }
- }
- return _cacheMesh;
- }
- private Mesh Create(float sideLength, float angleDegree)
- {
- Mesh mesh = new Mesh();
- Vector3[] vertices = new Vector3[3];
- float angle = Mathf.Deg2Rad * angleDegree;
- float halfAngle = angle / 2;
- vertices [0] = Vector3.zero;
- float cosA = Mathf.Cos (halfAngle);
- float sinA = Mathf.Sin (halfAngle);
- vertices [1] = new Vector3 (cosA * sideLength, 0, sinA * sideLength);
- vertices [2] = new Vector3 (cosA * sideLength, 0, -sinA * sideLength);
- int[] triangles = new int[3];
- triangles [0] = 0;
- triangles [1] = 1;
- triangles [2] = 2;
- mesh.vertices = vertices;
- mesh.triangles = triangles;
- Vector2[] uvs = new Vector2[vertices.Length];
- for (int i = 0; i < uvs.Length; i++)
- {
- uvs[i] = Vector2.zero;
- }
- mesh.uv = uvs;
- return mesh;
- }
- private bool checkDiff(float sideLength, float angleDegree)
- {
- return (int)((sideLength - this._sideLength) * SIDE_LENGTH_PRECISION) != 0 ||
- (int)((angleDegree - this._angleDegree) * ANGLE_DEGREE_PRECISION) != 0;
- }
- }
- }
为GameObject的MeshRenderer添加材质,我们就可以看到有颜色的三角形了。因为uv值都为0,所以是单一颜色。不过没关系,下一堂课,我们会为三角形添加不同的纹理。
版权声明:本文为博主原创文章,未经博主允许不得转载。
Unity---------Mesh理解的更多相关文章
- Unity Mesh 初体验
什么是Mesh Mesh是Unity中的一个组件,称为网格组件.通俗的讲,Mesh是指模型的网格,3D模型是由多边形拼接而成,而一个复杂的多边形,实际上是由多个三角面拼接而成.所以一个3D模型的表面是 ...
- Unity内存理解(转)
Unity3D 里有两种动态加载机制:一个是Resources.Load,另外一个通过AssetBundle,其实两者区别不大. Resources.Load就是从一个缺省打进程序包里的AssetBu ...
- Unity 全面理解加载和内存管理
最近一直在和这些内容纠缠,把心得和大家共享一下: Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBundle,其实两者本质上我理解没有什么区别.Resources ...
- 初识Unity Mesh
Mesh概念:Mesh是Unity中的一个组件,称为网格组件.通俗的讲,Mesh是指模型的网格,3D模型是由多边形拼接而成,而多边形实际上是由多个三角形拼接而成的.所以一个3D模型的表面其实是由多个彼 ...
- unity, mesh Collider
关闭mesh Renderer以便查看mesh Collider "For Unity 5, we must also select "Convex" on the Me ...
- Unity mesh 合并
簡介: 基本上就是把 很多物體結合成一個物體 的作法,這種做法有很多優點,例如:1. 提高效能2. 統一材質 (只要建立一個材質,就能控制.分配給所有物體)3. 動畫控制方便 (像是你要在 Unity ...
- unity meshrender理解
网格渲染器,其中unity里面多有的材质在渲染的时候都是会划分成三角形的,所以当添加一些物体的时候,例如3d text的时候,默认添加网格渲染器. 最常用的就是获取材质. 下面是一个利用网格渲染器获得 ...
- unity Mesh(网格)的使用
创建两个三角形合成的矩形网格: GameObject obj= new GameObject(); MeshRenderer meshRenderer=obj.AddComponent<Mesh ...
- [转]解读Unity中的CG编写Shader系列5——理论知识
经过前面的系列文章中的三个例子,尽管代码简单,但是我想应该还有些地方没有100%弄明白,我们现在得回过头来补充一些必备的数学.图形学知识 1.图形管道第一个例子中我有提到顶点着色和片段着色在整个图形绘 ...
- 蚂蚁金服研发的金融级分布式中间件SOFA背后的故事
导读:GIAC大会期间,蚂蚁金服杨冰,黄挺等讲师面向华南技术社区做了<数字金融时代的云原生架构转型路径>和<从传统服务化走向Service Mesh>等演讲,就此机会,高可用架 ...
随机推荐
- VMware的快照和克隆总结
原文:https://www.cnblogs.com/zxz1987/p/6480833.html 多重快照功能简介: 快照的含义:对某一个特定文件系统在某一个特定时间内的一个具有只读属性的镜像.当 ...
- if __name__ == '__main__' 含义
if __name__ == '__main__': app.run(host = '0.0.0.0',debug=app.config['DEBUG']) 1.是项目入口的含义2.如果是在生产环境下 ...
- 利用 fdisk进行分区
):fdisk命令参数 p:打印分区表. n:新建一个新分区. d:删除一个新分区. q:退出不保存. w:退出且保存. 例子: 先看下磁盘: root@archiso ~ # lsblk 在这里对磁 ...
- 设置模式之单例模式(附上一个Objective-C编写的播放音乐的单例类)
在查阅Cocoa Touch开发文档时,会发现框架中随处可见的大量单例类,比如说,UIApplication.NSFileManager 等. UIApplication 框架中极为常用的一个单例类, ...
- vpnbook.py
vpnbook提供免费的vpn服务,当然了,免费的肯定有限制,vpnbook的限制在于速度,一般只有10kb/s左右,用来看看网页还可以,当主力就不够了. 话说IE存在的意义就是用来下载其它浏览器,我 ...
- 5. 支持向量机(SVM)软间隔
1. 感知机原理(Perceptron) 2. 感知机(Perceptron)基本形式和对偶形式实现 3. 支持向量机(SVM)拉格朗日对偶性(KKT) 4. 支持向量机(SVM)原理 5. 支持向量 ...
- jsp----标签编程(JSTL)
标签编程简介 JSP的开发是在HTML代码中嵌入了大量的Java代码,但是这样一来会使得JSP页面中充满了Java程序,修改或维护起来非常的不方便, 定义一个简单的标签----空标签 要想实现一个标签 ...
- [转]Oracle trunc()函数的用法
原文地址:http://www.cnblogs.com/gengaixue/archive/2012/11/21/2781037.html 1.TRUNC(for dates) TRUNC函数为指定元 ...
- Eclipse源代码分析
Eclipse源代码分析 一.概述走入Eclipse的内核,看看它到底是怎么工作的? 1.Eclipse源代码 下载地址:http://download.eclipse.org/eclipse/dow ...
- kafka集群中jmx端口设置
jmx端口主要用来监控kafka集群的. 在启动kafka的脚本kafka-server-start.sh中找到堆设置,添加export JMX_PORT="9999" if [ ...