Unity中Quad顶点与localScale不匹配的原因及绘图方法咨询
问题解答:Quad顶点与Scale的关系及前方绘制正方形方案
一、为什么Quad的Mesh顶点是正方形,但localScale不是正方形比例?
这其实是Unity中Mesh和Transform分工的正常表现,我给你拆解下逻辑:
- Unity默认的Quad Mesh,顶点存储的是未经过任何缩放的原始单位正方形数据——也就是你看到的
(-0.5, -0.5)这类坐标,它的作用是定义Mesh的基础形状,不会因为物体的缩放、移动而改变。 - 而
transform.localScale是Transform组件对Mesh的实时缩放系数,它会在渲染阶段动态应用到原始顶点上,最终让Quad显示成你设置的长方形比例,但不会修改Mesh本身的顶点数据。
举个验证例子:把原始顶点(-0.5,-0.5,0)和localScale=(6.4,4.8,0)做乘法,得到(-3.2,-2.4,0),这才是这个顶点在物体局部空间的实际位置,你打印的只是Mesh的“原始蓝图”,和缩放无关~
二、如何利用这些顶点在Quad前方绘制另一个正方形?
核心思路是把原始Mesh顶点转换成世界空间的实际位置,再沿Quad的前方向偏移,下面给你几种实用方案:
方案1:用LineRenderer绘制空心正方形(运行时可见)
public GameObject quad; public LineRenderer lineRenderer; // 记得在Inspector赋值或动态创建 void Start() { if (quad == null || lineRenderer == null) return; MeshFilter meshFilter = quad.GetComponent<MeshFilter>(); Vector3[] originalVertices = meshFilter.mesh.vertices; Transform quadTrans = quad.transform; // 1. 将原始顶点转换为世界空间的实际位置(应用缩放和物体位置) Vector3[] worldVertices = new Vector3[4]; for (int i = 0; i < originalVertices.Length; i++) { Vector3 scaledLocalVertex = Vector3.Scale(originalVertices[i], quadTrans.localScale); worldVertices[i] = quadTrans.TransformPoint(scaledLocalVertex); } // 2. 沿Quad前方向偏移,避免和原Quad重叠 float forwardOffset = 0.1f; for (int i = 0; i < worldVertices.Length; i++) { worldVertices[i] += quadTrans.forward * forwardOffset; } // 3. 设置LineRenderer顶点,闭合正方形(需要重复第一个顶点) lineRenderer.positionCount = 5; lineRenderer.SetPositions(new Vector3[] { worldVertices[0], worldVertices[2], worldVertices[1], worldVertices[3], worldVertices[0] }); }
方案2:用Gizmos绘制(编辑器Scene视图调试用)
public GameObject quad; void OnDrawGizmos() { if (quad == null) return; MeshFilter meshFilter = quad.GetComponent<MeshFilter>(); Vector3[] originalVertices = meshFilter.mesh.vertices; Transform quadTrans = quad.transform; Vector3[] worldVertices = new Vector3[4]; for (int i = 0; i < originalVertices.Length; i++) { Vector3 scaledLocalVertex = Vector3.Scale(originalVertices[i], quadTrans.localScale); worldVertices[i] = quadTrans.TransformPoint(scaledLocalVertex); } // 偏移到前方 float offset = 0.1f; for (int i = 0; i < worldVertices.Length; i++) { worldVertices[i] += quadTrans.forward * offset; } // 绘制四条边 Gizmos.color = Color.red; Gizmos.DrawLine(worldVertices[0], worldVertices[2]); Gizmos.DrawLine(worldVertices[2], worldVertices[1]); Gizmos.DrawLine(worldVertices[1], worldVertices[3]); Gizmos.DrawLine(worldVertices[3], worldVertices[0]); }
额外方案:生成实体正方形(最简单的方式)
如果不需要纠结原始顶点,直接实例化新Quad更高效:
public GameObject quad; void Start() { if (quad == null) return; GameObject newQuad = GameObject.CreatePrimitive(PrimitiveType.Quad); // 设置位置为原Quad前方偏移 newQuad.transform.position = quad.transform.position + quad.transform.forward * 0.1f; // 同步缩放和旋转 newQuad.transform.localScale = quad.transform.localScale; newQuad.transform.rotation = quad.transform.rotation; }
内容的提问来源于stack exchange,提问作者Faizuddin Mohammed
相关产品推荐
相关产品推荐

