using UnityEngine; using System.Collections.Generic; [RequireComponent(typeof(MeshCollider))] public class MeshColliderGizmo : MonoBehaviour { [Tooltip("Gizmo显示颜色")] public Color lineColor = new Color(0, 1, 1, 0.8f); [Tooltip("线框宽度")] public float lineWidth = 1.0f; [Tooltip("是否在运行时显示")] public bool showInPlayMode = true; [Tooltip("是否只显示边缘")] public bool showEdgesOnly = true; private MeshCollider _meshCollider; private Mesh _mesh; private List _vertices = new List(); private List _triangles = new List(); private List _linePoints = new List(); private Material _glMaterial; private Matrix4x4 _localToWorldMatrix; private void Awake() { _meshCollider = GetComponent(); InitializeMeshData(); InitializeGLMaterial(); } private void InitializeMeshData() { // 尝试获取网格数据 MeshFilter meshFilter = GetComponent(); if (meshFilter != null && meshFilter.sharedMesh != null) { _mesh = meshFilter.sharedMesh; } else if (_meshCollider.sharedMesh != null) { _mesh = _meshCollider.sharedMesh; } if (_mesh != null) { _vertices.Clear(); _triangles.Clear(); _mesh.GetVertices(_vertices); _mesh.GetTriangles(_triangles, 0); GenerateLinePoints(); } else { Debug.LogWarning("未找到有效的Mesh资源", this); } } private void InitializeGLMaterial() { // 创建用于GL绘制的材质 _glMaterial = new Material(Shader.Find("Hidden/Internal-Colored")); _glMaterial.hideFlags = HideFlags.HideAndDontSave; _glMaterial.SetInt("ZWrite", 0); _glMaterial.SetInt("ZTest", (int)UnityEngine.Rendering.CompareFunction.Always); } private void GenerateLinePoints() { if (showEdgesOnly) { // 只显示边缘线(去重处理) HashSet edgeSet = new HashSet(); _linePoints.Clear(); for (int i = 0; i < _triangles.Count; i += 3) { AddEdge(_triangles[i], _triangles[i + 1], edgeSet); AddEdge(_triangles[i + 1], _triangles[i + 2], edgeSet); AddEdge(_triangles[i + 2], _triangles[i], edgeSet); } } else { // 显示所有三角形线 _linePoints.Clear(); for (int i = 0; i < _triangles.Count; i += 3) { _linePoints.Add(_vertices[_triangles[i]]); _linePoints.Add(_vertices[_triangles[i + 1]]); _linePoints.Add(_vertices[_triangles[i + 1]]); _linePoints.Add(_vertices[_triangles[i + 2]]); _linePoints.Add(_vertices[_triangles[i + 2]]); _linePoints.Add(_vertices[_triangles[i]]); } } } private void AddEdge(int v1, int v2, HashSet edgeSet) { // 创建唯一的边ID,避免重复 long edgeId = (long)Mathf.Min(v1, v2) << 32 | Mathf.Max(v1, v2); if (edgeSet.Contains(edgeId)) return; edgeSet.Add(edgeId); _linePoints.Add(_vertices[v1]); _linePoints.Add(_vertices[v2]); } private void Update() { _localToWorldMatrix = transform.localToWorldMatrix; } private void OnRenderObject() { if (!showInPlayMode || _mesh == null || _linePoints.Count == 0 || _glMaterial == null) return; // 设置材质和颜色 _glMaterial.SetPass(0); GL.PushMatrix(); GL.MultMatrix(_localToWorldMatrix); GL.Color(lineColor); // 设置线宽 GL.Begin(GL.LINES); for (int i = 0; i < _linePoints.Count; i++) { GL.Vertex(_linePoints[i]); } GL.End(); GL.PopMatrix(); } // 编辑器下的Gizmo预览 #if UNITY_EDITOR private void OnDrawGizmos() { if (!Application.isPlaying && _mesh != null) { Gizmos.color = lineColor; Gizmos.matrix = transform.localToWorldMatrix; Gizmos.DrawWireMesh(_mesh); } } #endif }