Unity给物体添加网格(Wire)绘制的方法参考

devtools/2024/12/21 21:25:02/

先看效果:       

再看代码:

using System.Collections.Generic;
using UnityEngine;public class WireMesh : MonoBehaviour
{[SerializeField]Material material;void Start(){Mesh mesh = OptimizeMesh(GetComponent<MeshFilter>().mesh);GameObject objWire = new(gameObject.name + "_wire");objWire.layer = LayerMask.NameToLayer("Wire");Mesh meshWird = new() { vertices = mesh.vertices };int[] edges = GetEdges(mesh);meshWird.SetIndices(edges, MeshTopology.Lines, 0);//-------------------------------------------------------------------------------------------MeshFilter meshFilter = objWire.AddComponent<MeshFilter>();meshFilter.mesh = meshWird;MeshRenderer meshRenderer = objWire.AddComponent<MeshRenderer>();meshRenderer.material = material;objWire.transform.SetParent(transform);objWire.transform.localPosition = Vector3.zero;objWire.transform.localRotation = Quaternion.identity;objWire.transform.localScale = Vector3.one;int[] GetEdges(Mesh mesh){var hashEdges = new HashSet<(int, int)>();var triangles = mesh.triangles;for (int i = 0; i < triangles.Length; i += 3){AddEdge(triangles[i], triangles[i + 1]);AddEdge(triangles[i + 1], triangles[i + 2]);AddEdge(triangles[i + 2], triangles[i]);}List<int> listTriangle = new();foreach (var val in hashEdges){listTriangle.Add(val.Item1);listTriangle.Add(val.Item2);}return listTriangle.ToArray();void AddEdge(int id1, int id2){var edge = (Mathf.Min(id1, id2), Mathf.Max(id1, id2));hashEdges.Add(edge); // 只添加唯一组合}}}Mesh OptimizeMesh(Mesh originalMesh, bool recalculate = false){Vector3[] originalVertices = originalMesh.vertices;int[] originalTriangles = originalMesh.triangles;Dictionary<Vector3, int> uniqueVertices = new Dictionary<Vector3, int>();List<Vector3> newVertices = new List<Vector3>();List<int> newTriangles = new List<int>();// Re-index verticesfor (int i = 0; i < originalVertices.Length; i++){Vector3 vertex = originalVertices[i];if (!uniqueVertices.ContainsKey(vertex)){uniqueVertices[vertex] = newVertices.Count;newVertices.Add(vertex);}}// Map old indices to new onesfor (int i = 0; i < originalTriangles.Length; i++){int oldIndex = originalTriangles[i];int newIndex = uniqueVertices[originalVertices[oldIndex]];newTriangles.Add(newIndex);}// Create new optimized meshMesh optimizedMesh = new(){vertices = newVertices.ToArray(),triangles = newTriangles.ToArray()};//if (recalculate){optimizedMesh.RecalculateNormals();optimizedMesh.RecalculateBounds();} return optimizedMesh;}
}

        这个代码给一个物体添加一个与原始物体重叠的网格渲染的物体。

        这里面涉及到了一些知识点和操作方法,逐条说一下。

        首先是网格内容优化。这里说的优化只是Mesh记录数据量的优化,并不是说能在渲染速度上的优化。为什么这么说呢?当我们把一个模型文件导入到unity中后,不管原来的网格数据是怎样的,unity总是会让顶点数组中的顶点(Vector3)复制出多个来,假设一个fbx格式的立方体有8个顶点,但Unity在使用时会显示Mesh包含24个顶点,不知道是否是出于提升渲染速度的考虑。但我们要尽可能优化这个点数,这样索引的最大值也会变小,也能让我们渲染的wire的边变少,否则同样的边会重复渲染多次。这里OptimizeMesh方法将Mesh中位置重叠的顶点去掉,同时也重置了面索引。在GetEdges方法中使用HashSet,这保证了不出现重叠的边。最后我们让Mesh使用了MeshTopology.Lines方式渲染,就得到了最终的结果。

        


http://www.ppmy.cn/devtools/121132.html

相关文章

python贪吃蛇小游戏

1.简介 使用了turtle库来创建图形界面&#xff0c;你可以使用键盘的W、A、S、D键来控制蛇的移动方向。蛇吃到食物后&#xff0c;身体会增长&#xff0c;如果蛇撞到自己或者游戏边界&#xff0c;游戏就会结束。 2. 代码 import turtle import time import randomdelay 0.1# …

【三步 完全离线搭建 openwebui 】

完全离线linux 版open webui 的搭建 1.在具有网络连接的环境中下载whl 在有网络的环境&#xff0c;使用pip download可以保存所有的依赖包,可以使用-i 指定清华的镜像源加速下载速度。 # 命令&#xff1a; pip download <package_name> --only-binary:all: --wheel --…

C#知识|设计模式的分类及认识

继承是为了解决代码复用问题和子类扩展问题&#xff1b;控件二次开发中经常用到&#xff1b; 接口解决扩展和团队协作问题&#xff0c;实现多态和项目框架设计&#xff1b; 继承接口&#xff1a;可以相互弥补不足&#xff0c;接口弥补了继承不能多重继承的问题&#xff0c;同…

828华为云征文|WordPress部署

目录 前言 一、环境准备 二、远程连接 三、WordPress简介 四、WordPress安装 1. 基础环境安装 ​编辑 2. WordPress下载与解压 3. 创建站点 4. 数据库配置 总结 前言 WordPress 是一个非常流行的开源内容管理系统&#xff08;Content Management System, CMS&#xf…

主流前端框架的详细对比和选择建议

前端框架的选择对于现代Web开发至关重要&#xff0c;影响到开发效率、代码可维护性以及用户体验。以下是对几种主流前端框架的详细对比和选择建议。 一、前端框架概述 前端框架是为了简化Web开发而设计的一组工具和库&#xff0c;帮助开发者构建用户界面、管理状态以及处理与…

【C语言】内存函数的使用和模拟实现

文章目录 一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset的使用四、memcmp的使用 一、memcpy的使用和模拟实现 在之前我们学习了使用和模拟实现strncpy函数&#xff0c;它是一个字符串函数&#xff0c;用来按照给定的字节个数来拷贝字符串&#xff0c;那么问…

spring揭秘25-springmvc03-其他组件(文件上传+拦截器+处理器适配器+异常统一处理)

文章目录 【README】【1】文件上传与MultipartResolver【1.1】使用MultipartResolver进行文件上传【1.2】springmvc处理multipart多部件请求流程【1.3】使用springmvc上传文件代码实现&#xff08;springmvc6.10版本&#xff09;&#xff1a; 【2】Handler与HandlerAdaptor&…

基于SSM+微信小程序的校园二手数码交易平台系统(二手3)(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于ssm微信小程序的校园二手数码交易平台满足了不同用户的功能需求&#xff0c;包括用户、卖家以及管理员&#xff0c;下面对这不同用户的功能需求进行简介。 &#xff08;1&#xff09…