您现在的位置是:网站首页> 编程资料编程资料
游戏开发进阶Unity网格(Mesh\动态合批\骨骼动画\蒙皮)_相关技巧_
2023-05-27
742人已围观
简介 游戏开发进阶Unity网格(Mesh\动态合批\骨骼动画\蒙皮)_相关技巧_
一、前言
嗨,大家好,我是新发。
有同学私信我让我写一篇Unity网格相关的教程,

那我就带大家来一次Unity的网格探险之旅吧~
二、Hello Mesh
我背着旅行背包走在Unity的场景中,突然眼前出现了一棵树,

我走近一看,这棵树身上挂着MeshFilter和MeshRenderer组件,根据Unity探险手册记载,这个MeshFilter是网格过滤器,它会引用一个网格资源,我顺腾摸瓜,找到了对应的网格,

实在太美了,我久久伫立,这就是网格啊!
正当我欣赏着网格三角形时,突然世界暗了下来,眼前出现了一团火,

我又拿出了Unity探险手册,啊,这一定就是粒子系统了!它可以动态生成网格。

天外传来一阵打字声,场景中出现了一行看起来像文字的网格,作为一个具有多年Hello World经验的程序员,我看出了第一个单词应该是Hello,第二个单词…我知道了,

是Hello Mesh!

(此处为震撼人心的入场音乐)
三、萌新初识Mesh
1、引擎内置的Mesh
网格的英文名是Mesh,Unity萌新最先接触的网格应该就是引擎内置的Cube(正方体)、Capsule(胶囊体)、Cylinder(圆柱体)、Plane(平面)、Sphere(球体)、Quad(四边形),如下

事实上,我们在Unity场景中,所有能被渲染出来的物体都会带有网格,比如3D模型、粒子特效、UI、文字等等。
2、Mesh是什么
从概念上讲,网格是图形硬件用来绘制复杂内容的构造。它至少包含一组定义3D空间中点的顶点,以及一组连接这些点的三角形,实际上还包含法线、顶点颜色纹理坐标等信息,这些三角形构成了网格所代表的任何表面。
我们可以看下Unity的Mesh类,Mesh的属性和方法很多,我这里列举几个比较常用的,如下
// 顶点坐标数组 public Vector3[] vertices { get; set; } // 法线向量数组 public Vector3[] normals { get; set; } // 顶点颜色数组 public Color[] colors { get; set; } // 三角形序列数组,每三个数字为一组 public int[] triangles { get; set; } // uv坐标数组 public Vector2[] uv { get; set; } // 重新计算法线,在修改完顶点后,通常会更新法线来反映新的变化,注意,法线是根据共享的顶点计算出来的。 public void RecalculateNormals(); // 从法线和纹理坐标重新计算网格的切线。修改网格的顶点和法线之后,如果网格使用引用法线贴图的着色器进行渲染,则切线需要更新。 public void RecalculateTangents(); // 重新计算从网格包围体的顶点, 在修改顶点后需要这个函数以确保包围体是正确的,赋值三角形将自动重新计算这个包围体。 public void RecalculateBounds(); 画个图,方便大家有个直观印象,

三、Mesh的创建方式
1、第三方建模软件
建模本质上就是建网格,我们可以事先通过第三方建模软件来创建模型网格,

常见的建模软件比如

3DS MAX官网:https://www.autodesk.com/products/3ds-max/overview

MAYA官网:https://www.autodesk.com/products/maya/overview

blender官网:https://www.blender.org/
2、Unity建模插件:ProBuilder
Unity官方提供了一个可以用来创建和自定义几何体的工具ProBuilder,我们可以在Unity的Package Manager中下载到这个插件,

使用ProBuilder我们可以直接在Unity中创建或编辑简单的几何体,不用通过第三方建模软件,提升了效率,方便快速搭建场景原型,

3、程序动态生成网格
网格也可以是程序动态生成的,比如粒子系统的网格就是动态生成的,

又比如文字,也是程序动态生成网格,

文章后面我还会手把手教你如何使用纯代码来构建网格,这里先不急着写代码,我们继续探寻网格的秘密先~
四、Unity中如何显示网格
在Unity中,我们要显示一个网格,需要用到两个组件:MeshFilter和MeshRenderer。
注:你也可以直接使用SkinnedMeshRenderer组件,与MeshFilter和MeshRenderer的区别我下文会讲。
1、MeshFilter:网格过滤器
MeshFilter是网格过滤器,我们需要通过它设置引用的网格资源,比如这里引用的是一个Cube(正方体)网格。

我们可以看下MeshFilter.cs的源码,
[RequireComponent(typeof(Transform))] [NativeHeader("Runtime/Graphics/Mesh/MeshFilter.h")] public sealed partial class MeshFilter : Component { [RequiredByNativeCode] // MeshFilter is used in the VR Splash screen. private void DontStripMeshFilter() {} extern public Mesh sharedMesh { get; set; } extern public Mesh mesh {[NativeName("GetInstantiatedMeshFromScript")] get; [NativeName("SetInstantiatedMesh")] set; } } MeshFilter只有两个属性:mesh和sharedMesh,
我们查看Unity的官方手册,看看mesh与sharedMesh的区别:https://docs.unity3d.com/ScriptReference/MeshFilter.html

我来解读一下,mesh访问的是一个Mesh资源的实例(副本),这意味着我们修改这个mesh并不会修改到原始资源本身,改的只是Mesh的实例(副本)。
而sharedMesh是原始资源的引用,如果修改了sharedMesh,比如修改顶点坐标,那么原始资源也会被修改。
画成图大概是这样子:

这里我顺手写个随机修改Mesh顶点坐标的脚本,如下,将下面这个RandoMeshmVertices脚本挂到MeshFilter组件所在的物体上即可,
// RandoMeshmVertices.cs // 随机修改Mesh顶点坐标 using UnityEngine; public class RandoMeshmVertices: MonoBehaviour { // Mesh的实例 MeshFilter meshFilt
点击排行
本栏推荐
