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

news/2024/12/22 0:00:46/

先看效果:       

再看代码:

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/news/1534002.html

相关文章

力扣 —— 跳跃游戏

题目一(中等) 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&…

Qt(9.28)

widget.cpp #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {QPushButton *btn1 new QPushButton("登录",this);this->setFixedSize(640,480);btn1->resize(80,40);btn1->move(200,300);btn1->setIcon(QIcon("C:…

奔驰EQS450suv升级增强AR抬头显示HUD案例分享

以下是奔驰 EQS450 SUV 升级增强版 AR 抬头显示的一般改装案例步骤及相关信息&#xff1a; 配件&#xff1a;通常包括显示屏、仪表模块、饰板等。 安装步骤&#xff1a; 1. 拆下中控的仪表。 2. 在仪表上预留位置切割出合适的孔位&#xff0c;用于安装显示器。 3. 将显示器…

【算法】分治:归并排序之 315.计算右侧小于当前元素的个数(hard)

hard太难了啦&#xff0c;大家还是酌情做题&#xff0c;不要浪费太多时间。 相关题目&#xff1a;LCR 170. 交易逆序对的总数 - 力扣&#xff08;LeetCode&#xff09; 目录 1、题目链接 2、题目介绍 3、解法 4、代码 1、题目链接 315. 计算右侧小于当前元素的个数 - 力扣…

小阿轩yx-案例:项目发布基础

小阿轩yx-案例&#xff1a;项目发布基础 前言 随着软件开发需求及复杂度的不断提高&#xff0c;团队开发成员之间如何更好地协同工作以确保软件开发的质量已经慢慢成为开发过程中不可回避的问题。Jenkins 自动化部署可以解决集成、测试、部署等重复性的工作&#xff0c;工具集…

机器学习-KNN

KNN&#xff1a;K最邻近算法&#xff08;K-Nearest Neighbor,KNN&#xff09; 用特征空间中距离待分类对象的最近的K个样例点的类别来预测。 投票法&#xff1a;K 个样例的对数类别。 k1:最近邻分类 k 通常是奇数&#xff08;因为我们根据这个K数据判断类别&#xff0c;如果…

前端框架对比与选择

前端框架对比与选择 1. React2. Vue.js3. Angular4. Svelte5. Next.js 和 Nuxt.js选择建议&#xff1a; 在前端开发中&#xff0c;选择合适的前端框架对于开发效率和项目的长期维护非常重要。以下是当前主流前端框架的对比&#xff0c;以及适用场景分析&#xff1a; 1. React …

【C++】面向对象编程的三大特性:深入解析多态机制

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…