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

server/2024/12/21 20:37:24/

先看效果:       

再看代码:

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/server/126819.html

相关文章

遮罩解决图片悬浮操作看不到的情况

未悬浮效果 悬浮效果 如果仅仅是添加绝对定位&#xff0c;那么遇到白色图片&#xff0c;就会看不到白色字体。通过遮罩&#xff08;绝对定位透明度&#xff09;就可以解决这个问题。 <script setup> </script><template><div class"box"><…

蓝桥杯-财务管理

#include<stdio.h> int main() { int i 1; float yue 0,nian0; printf("请输入每月结余:\n "); while (i < 12) { scanf_s("%f", &yue); i; nian yue; } printf("平均月结余&#xff1a…

论文提纲怎么写?分享5款AI论文写作软件

在学术研究和写作过程中&#xff0c;撰写高质量的论文是一项挑战性的任务。幸运的是&#xff0c;随着人工智能技术的发展&#xff0c;AI论文写作工具逐渐成为帮助学者和学生提高写作效率的重要工具。这些工具不仅能够提高写作效率&#xff0c;还能帮助简化复杂的写作流程&#…

土地规划中的公共设施布局:科学规划,赋能土地高效利用的艺术

在城市与区域发展的宏大叙事中&#xff0c;公共设施布局如同血管与神经网络&#xff0c;支撑着城市的脉动与感知。合理规划公共设施布局对于提升土地使用效率、促进社会公平、增强居民福祉至关重要。本文将深入探讨如何通过科学方法与创新策略&#xff0c;实现公共设施的高效布…

使用Scikit-image进行图像处理入门

简介 在数据科学的广阔领域中&#xff0c;图像处理占据了重要的一席之地&#xff0c;为分析和处理视觉数据提供了各种工具和技术。Python 拥有丰富的库生态系统&#xff0c;为图像处理提供了多种选择&#xff0c;其中&#xff0c;scikit-image 凭借其强大且易用的功能脱颖而出…

目标检测 DETR(2020)

文章目录 前言backbone位置编码&#xff08;二维&#xff09;encoder、decoderprediction heads损失函数计算 前言 DETR全称是Detection Transformer&#xff0c;是首个基于Transformer的端到端目标检测网络&#xff0c;最大的特点就是不需要预定义的先验anchor&#xff0c;也…

vue admin 若依框架 解决无权限时进入死循环的问题 auths

核心原因&#xff1a; if (auths && auths.length > 0) { // like12 find bug,数组为空[]时依然会进入死循环 原来为&#xff1a;if (auths) // 获取用户信息getInfo({ commit, state }) {return new Promise((resolve, reject) > {getInfo(state.token).then(…

极客兔兔Gee-Cache Day1

极客兔兔7Days GeeCache - Day1 interface{}&#xff1a;任意类型 缓存击穿&#xff1a;一个高并发的请求查询一个缓存中不存在的数据项&#xff0c;因此这个请求穿透缓存直接到达后端数据库或数据源来获取数据。如果这种请求非常频繁&#xff0c;就会导致后端系统的负载突然…