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. PC 网页 布局图

  2. Spring————IOC入门学习

    Spring----入门学习 简介 优点 Spring是一个开源的免费的框架(容器)! Spring是一个轻量级,非入侵式的框架 控制反转(IOC),面向切面编程(AOP) 支持对事务的处理,对框架整 ...

  3. 聊聊x86计算机启动发生的事?

    大家好,我是呼噜噜,最近在看linux早期内核0.12的源码,突然想到一个困扰自己好久的问题:当我们按下电源键,计算机发生了什么?神秘地址0x7C00究竟是什么?操作系统又是如何被加载到硬件中的?带着 ...

  4. 幻兽帕鲁 Palworld 私有服务器一键部署教程

    <幻兽帕鲁>(日语:パルワールド,英语:Palworld) 是由日本开发商 Pocket Pair 推出的一款动作冒险生存游戏.游戏设定在一个由类似动物的生物 "帕鲁" ...

  5. [转帖]TiUP 常见运维操作

    https://docs.pingcap.com/zh/tidb/stable/maintain-tidb-using-tiup 本文介绍了使用 TiUP 运维 TiDB 集群的常见操作,包括查看集群 ...

  6. [转帖]修改jmeter内存配置(win&mac&linux)

    目录 一.背景: 二.win环境下修改jmeter内存 三.mac&linux环境下修改jmeter内存 四.验证内存是否修改成功 一.背景: 在进行大数据.高并发压测的过程性,有时会遇上JM ...

  7. [转帖]金仓数据库KingbaseES V8R6索引坏块故障处理

    案例说明: 在执行表数据查询时,出现下图所示错误,索引故障导致表无法访问,后重建索引问题解决.本案例复现了此类故障解决过程. 适用版本: KingbaseES V8R3/R6 一.创建测试环境 # 表 ...

  8. jconsole的简单学习

    摘要 jconsole 是JDK自带的一款图形化监测工具 他可以监测本地程序,也可以检测远程的机器 在没有其他监控手段可以使用的情况下可以快速进行必要的监测 使用方法也比较简单. 本地监控 jcons ...

  9. Docker 运行 Redis Rabbitmq seata-server ftp 的简单办法

    公司里面用到了很多组件, 发现安装二进制太麻烦了, 所以想用Docker 进行安装. 这里面简单给总结一下就不在折腾了.. 1. redis docker run -d -p 6379:6379 -- ...

  10. JDK内嵌指令的简单学习

    java 可以使用 java -jar的方式启动服务 日常工作中用到的比较少 javac 可以将.java 文件编译成 .class中间代码 这个工具开发编写代码中是经常需要使用的, jenkins ...