Unity Quad 绘制四边形
思路
- 自定义QuadMesh数据结构
- 存储Quad数据
- 同时转换Unity默认的Mesh
- 利用GL绘制线框
- 效果
- 不足之处
- 不能设置线框宽度
- 不能背面剔除线框
- 有锯齿
代码
- QuadMesh.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149using System;
using System.Collections.Generic;
using UnityEngine;
[Serializable]
public class QuadMesh
{
[Serializable]
private struct Point
{
public Vector3 position;
public int index;
}
[Serializable]
private struct Quad
{
public Point a, b, c, d;
public int index;
}
private List<Quad> m_quads;
private List<Point> m_points;
private List<Vector3> m_vertices;
private List<int> m_triangles;
private Mesh m_mesh;
public QuadMesh()
{
m_quads = new List<Quad>();
m_points = new List<Point>();
m_vertices = new List<Vector3>();
m_triangles = new List<int>();
}
public Mesh GetMesh()
{
m_mesh = new Mesh();
m_mesh.vertices = m_vertices.ToArray();
m_mesh.SetIndices(m_triangles, MeshTopology.Quads, 0);
return m_mesh;
}
public void BuildQuads(Vector3[] vertices, int[] indices)
{
m_quads.Clear();
m_points.Clear();
m_vertices.Clear();
m_triangles.Clear();
int num = indices.Length / 4;
if (num < 1 || vertices.Length < 4) return;
foreach (var vertex in vertices)
{
AddPoint(vertex);
}
for (int i = 0; i < num; i++)
{
var p0 = m_points[indices[i * 4 + 0]];
var p1 = m_points[indices[i * 4 + 1]];
var p2 = m_points[indices[i * 4 + 2]];
var p3 = m_points[indices[i * 4 + 3]];
AddQuad(p0, p1, p2, p3);
}
}
private Point AddPoint(Vector3 pos)
{
var point = new Point
{
position = pos,
index = m_vertices.Count
};
m_vertices.Add(pos);
m_points.Add(point);
return point;
}
private void AddQuad(Point a, Point b, Point c, Point d)
{
var quad = new Quad()
{
a = a,
b = b,
c = c,
d = d,
index = m_quads.Count
};
m_quads.Add(quad);
m_triangles.Add(a.index);
m_triangles.Add(b.index);
m_triangles.Add(c.index);
m_triangles.Add(d.index);
}
public void AddQuad(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
{
var p0 = AddPoint(a);
var p1 = AddPoint(b);
var p2 = AddPoint(c);
var p3 = AddPoint(d);
AddQuad(p0, p1, p2, p3);
}
public void DrawQuadLine(Matrix4x4 matrix, Color color)
{
DrawGL.WireframeMode();
GL.PushMatrix();
GL.MultMatrix(matrix);
foreach (var quad in m_quads)
{
GL.Begin(GL.LINE_STRIP);
GL.Color(color);
GL.Vertex(quad.a.position);
GL.Vertex(quad.b.position);
GL.Vertex(quad.c.position);
GL.Vertex(quad.d.position);
GL.Vertex(quad.a.position);
GL.End();
}
GL.PopMatrix();
}
public void Clear()
{
m_quads.Clear();
m_points.Clear();
m_vertices.Clear();
m_triangles.Clear();
}
public override string ToString()
{
return $"Verts Num : {m_vertices.Count} Quad Num : {m_quads.Count}";
}
} - QuadGrid.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter))]
[RequireComponent(typeof(MeshRenderer))]
public class QuadGrid : MonoBehaviour
{
public bool wireframe = true;
[Range(0, 10)] public float size = 1;
[Range(0, 100)] public int width = 10;
[Range(0, 100)] public int height = 10;
private QuadMesh m_quadMesh;
private Material m_material;
private Mesh m_mesh;
void OnEnable()
{
m_material = new Material(Shader.Find("Unlit/Texture"));
GetComponent<MeshRenderer>().sharedMaterial = m_material;
CreateGrid();
}
void CreateGrid()
{
m_quadMesh = new QuadMesh();
var vertices = new List<Vector3>();
var indices = new List<int>();
for (int i = 0; i < width + 1; i++)
{
for (int j = 0; j < height + 1; j++)
{
float x = i * size;
float y = j * size;
vertices.Add(new Vector3(x, 0, y));
if (i == width || j == height)
continue;
indices.Add(i * (height + 1) + j + 0);
indices.Add(i * (height + 1) + j + 1);
indices.Add((i + 1) * (height + 1) + j + 1);
indices.Add((i + 1) * (height + 1) + j + 0);
}
}
m_quadMesh.BuildQuads(vertices.ToArray(), indices.ToArray());
m_mesh = m_quadMesh.GetMesh();
GetComponent<MeshFilter>().mesh = m_mesh;
}
void OnRenderObject()
{
if (wireframe)
m_quadMesh.DrawQuadLine(transform.localToWorldMatrix, Color.black);
}
#if UNITY_EDITOR
[CustomEditor(typeof(QuadGrid))]
public class QuadGridEditor : Editor
{
public override void OnInspectorGUI()
{
var quadGrid = target as QuadGrid;
if (!quadGrid) return;
if (DrawDefaultInspector())
{
quadGrid.CreateGrid();
}
GUILayout.Label(quadGrid.m_quadMesh.ToString());
}
}
#endif
}
Unity Quad 绘制四边形
https://automask.github.io/wild/2022/06/28/lab/S_Unity_Quad/