152 lines
4.3 KiB
C#
152 lines
4.3 KiB
C#
|
|
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<Vector3> _vertices = new List<Vector3>();
|
|||
|
|
private List<int> _triangles = new List<int>();
|
|||
|
|
private List<Vector3> _linePoints = new List<Vector3>();
|
|||
|
|
private Material _glMaterial;
|
|||
|
|
private Matrix4x4 _localToWorldMatrix;
|
|||
|
|
|
|||
|
|
private void Awake()
|
|||
|
|
{
|
|||
|
|
_meshCollider = GetComponent<MeshCollider>();
|
|||
|
|
InitializeMeshData();
|
|||
|
|
InitializeGLMaterial();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void InitializeMeshData()
|
|||
|
|
{
|
|||
|
|
// 尝试获取网格数据
|
|||
|
|
MeshFilter meshFilter = GetComponent<MeshFilter>();
|
|||
|
|
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<long> edgeSet = new HashSet<long>();
|
|||
|
|
_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<long> 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
|
|||
|
|
}
|