1 仅绘制三角形网格

1)创建游戏对象

​ 创建一个空对象,重命名为 Grid,并在其下添加需要绘制网格的对象,如下:

​ 场景显示如下:

2)添加脚本组件

​ GridController.cs

using System;
using UnityEngine; public class GridController : MonoBehaviour { private void Start () {
ForAllChildren(transform, RebuildMesh);
} private void RebuildMesh(Transform transform) {
MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
if (meshFilter != null && meshFilter.mesh != null) {
int[] indices = MakeIndices(meshFilter.mesh.triangles);
meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
}
} private int[] MakeIndices(int[] triangles) {
int[] indices = new int[2 * triangles.Length];
for( int i = 0; i < triangles.Length; i += 3 ) {
for (int j = 0; j < 6; j++) {
// 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
}
}
return indices;
} private void ForAllChildren(Transform transform, Action<Transform> action) {
action.Invoke(transform);
for (int i = 0; i < transform.childCount; i++) {
ForAllChildren(transform.GetChild(i), action);
}
}
}

​ 说明: GridController 脚本组件挂在 Grid 对象上。

​ 运行效果:

3)给网格添加新材质

​ GridController.cs

using System;
using UnityEngine; public class GridController : MonoBehaviour {
public Material material; private void Start () {
ForAllChildren(transform, RebuildMesh);
} private void RebuildMesh(Transform transform) {
MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
MeshRenderer meshRenderer = transform.GetComponent<MeshRenderer>();
if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
meshRenderer.material = material;
int[] indices = MakeIndices(meshFilter.mesh.triangles);
meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
}
} private int[] MakeIndices(int[] triangles) {
int[] indices = new int[2 * triangles.Length];
for( int i = 0; i < triangles.Length; i += 3 ) {
for (int j = 0; j < 6; j++) {
// 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
}
}
return indices;
} private void ForAllChildren(Transform transform, Action<Transform> action) {
action.Invoke(transform);
for (int i = 0; i < transform.childCount; i++) {
ForAllChildren(transform.GetChild(i), action);
}
}
}

​ 运行效果:

2 绘制表面和三角形网格

​ 场景中所有对象同第 1 节,脚本组件如下:

​ GridController.cs

using System;
using UnityEngine;
using UnityEngine.Rendering; public class GridController : MonoBehaviour {
public Material material; private void Start () {
ForAllChildren(transform, RebuildMesh);
} private void RebuildMesh(Transform transform) {
MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
MeshRenderer meshRenderer = transform.GetComponent<MeshRenderer>();
if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
InitMaterials(meshRenderer);
int[] indices = MakeIndices(meshFilter.mesh.triangles);
InitSubMesh(meshFilter.mesh, indices, indices.Length / 3);
}
} private void InitMaterials(MeshRenderer meshRenderer) {
Material[] materials = new Material[meshRenderer.materials.Length + 1];
meshRenderer.materials.CopyTo(materials, 0);
materials[materials.Length - 1] = material;
meshRenderer.materials = materials;
} private void InitSubMesh(Mesh mesh, int[] indices, int divide) {
mesh.SetIndexBufferParams(indices.Length, IndexFormat.UInt32);
mesh.SetIndexBufferData(indices, 0, 0, indices.Length);
mesh.subMeshCount = 2; // 设置2个子网格
// 第一部分绘制三角形内部
SubMeshDescriptor subMeshDescriptor1 = new SubMeshDescriptor(0, divide, MeshTopology.Triangles);
mesh.SetSubMesh(0, subMeshDescriptor1);
// 第二部分绘制线段
SubMeshDescriptor subMeshDescriptor2 = new SubMeshDescriptor(divide, indices.Length - divide, MeshTopology.Lines);
mesh.SetSubMesh(1, subMeshDescriptor2);
} private int[] MakeIndices(int[] triangles) {
int[] indices = new int[3 * triangles.Length];
triangles.CopyTo(indices, 0);
for( int i = 0; i < triangles.Length; i += 3 ) {
for (int j = 0; j < 6; j++) {
// 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
indices[triangles.Length + 2 * i + j] = triangles[i + (j + 1) % 6 / 2];
}
}
return indices;
} private void ForAllChildren(Transform transform, Action<Transform> action) {
action.Invoke(transform);
for (int i = 0; i < transform.childCount; i++) {
ForAllChildren(transform.GetChild(i), action);
}
}
}

​ 运行效果:

​ 声明:本文转自【Unity3D】绘制物体表面三角形网格

【Unity3D】绘制物体表面三角形网格的更多相关文章

  1. Matlab绘图基础——绘制三维表面

    %绘制三维表面 ------------------------------------- %1.绘制线框图:mesh:每一条曲线称为mesh line %首先利用meshgrid函数产生平面区域内的 ...

  2. unity3D 游戏物体同时绑定单击、双击事件

    前言 在unity中我们常用的获取鼠标点击的方法有 在3D场景中,一般用在Update方法中,每一帧调用 void Update(){ )){ Debug.log("鼠标左键点击" ...

  3. Three.js之绘制物体的边框及修改lineWidth

    本博文主要记录如何使用three.js绘制物体的边框及修改其lineWidth.three.js是个技术点比较多,查询资料又比较少的框架,单单就这个修改lineWidth就是一个坑.先放一个动态的效果 ...

  4. Unity3D 角色(物体) 移动方法 合集

    1. 简介 在Unity3D中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position. 2. 通过Transform组件移动物体 Transform 组件用于描述物体在 ...

  5. 时光煮雨 Unity3D让物体动起来③—UGUI DoTween&Unity Native2D实现

    本文首发蛮牛,次发博客园.接系列 第一篇,第二篇,本文为第三篇,再次感谢“武装三藏”在前两篇无私且精彩的问题解答 写在最前,时光煮雨,为了怀念 以下引用曾今读过的一些教程文章 其实这3种动画都有它特定 ...

  6. unity3d游戏物体跟着鼠标方向移动

    效果:当点击鼠标左键时,游戏对象会朝鼠标点击的方向移动,类似魔兽争霸一样. 思路:把鼠标的坐标转化成世界坐标(鼠标默认是屏幕坐标),然后当点击鼠标时,物体将朝着鼠标的世界坐标方向移动. 如果你看到这的 ...

  7. unity3d中物体的控制

    一.物体的循环移动和旋转 思路:通过对时间的计算,每隔一段时间让物体旋转,实现来回移动. float TranslateSpeed = 0.02f; float TranslateSpeedTime ...

  8. Unity3d创建物体,寻找物体,加载物体,添加脚本

    GetCreateObject: using UnityEngine; public class GetCreateObject : MonoBehaviour { GameObject emptyG ...

  9. Unity3d 控制物体移动、旋转、缩放

    在Unity中通过利用 Input Manager(输入管理器)可以很简单的实现对一个物体进行移动.旋转.缩放操作. 演示代码: //通过虚拟轴控制物体移动.旋转.缩放 public class Mo ...

  10. 【转】Unity3d实现物体围绕某一点进行旋转

    1,让一个物体围绕某一点旋转,有几种方法?分别是什么? 答:在这个点处放一个空物体B,则问题变为A绕着B旋转, 方法1:B不动,A挂脚本实现transform的RotateAround(vector3 ...

随机推荐

  1. Linux-磁盘-di-目录查询-du-tree

  2. [转帖]快速定位MySQL数据库当前消耗CPU最高的sql语句

    概述 One of our customers recently asked whether it is possible to identify, from the MySQL side, the ...

  3. [转帖]【Kafka】Kafka配置参数详解

    Kafka配置参数详解 Kafka得安装与基本命令 Kafka配置参数 kafka生产者配置参数 kafka消费者配置参数 本篇文章只是做一个转载的作用以方便自己的阅读,文章主要转载于: Kafka核 ...

  4. [转帖]dd - Linux世界中的搬运工

    <存储工具系列文章>主要介绍存储相关的测试和调试工具,包括不限于dd.fio.vdbench.iozone.iometer.cosbench等性能负载工具,及strace等调试工具. dd ...

  5. 【DS】P9062 [Ynoi2002] Adaptive Hsearch&Lsearch(区间最近点对)

    Problem Link 给定平面上 \(n\) 个点,\(Q\) 次询问编号在 \([l,r]\) 内的点的最近点对.\(n,Q\le 2.5\times 10^5\). 技巧:平面网格化 乱搞都是 ...

  6. vue面试题(一)正在重新整理

    1.输入一个 URL到浏览器整个过程发生了什么?ok 1.浏览器查找当前 URL是否存有缓存,并检查这个缓存是否过期 2.DNS 解析 URL 对应的 IP 3.根据 IP 建立 TCP 连接(三次握 ...

  7. Vue3中readonly 和 shallowReadonly和toRaw

    1.readonly 深度只读 被readonly包裹的数据只能够读取. 是一个深度只读,不能够修改. 我们看一下面的代码. 我们想修改值,但是修改后视图无响应. 并且控制台警告目标为只读 reado ...

  8. 对象中是否有某一个属性是否存在有三种方法 in hasOwnProperty Object.hasOwn

    如何看某个对象中没有某一个属性 如果我们要检测对象是否拥有某一属性,可以用in操作符 var obj= { name: '类老师', age: 18, school: '家具' }; console. ...

  9. 【一】飞桨paddle【GPU、CPU】安装以及环境配置+python入门教学

    相关文章: [一]飞桨paddle[GPU.CPU]安装以及环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简 ...

  10. 强化学习从基础到进阶-常见问题和面试必知必答[4]::深度Q网络-DQN、double DQN、经验回放、rainbow、分布式DQN

    强化学习从基础到进阶-常见问题和面试必知必答[4]::深度Q网络-DQN.double DQN.经验回放.rainbow.分布式DQN 1.核心词汇 深度Q网络(deep Q-network,DQN) ...