在 3d模型上边绘制mesh是很平常的操作,如车轮压过的轨迹等等。
在场景中建一个空的gameobject, 然后添加meshfilter 和meshrender组件,
传入参数,把返回值赋值给meshfile.mesh对象就能在屏幕上看见了,代码如下:
有中间点的mesh绘制代码
public static Mesh CreateCurveMesh(MeshFilter meshFilter, Vector3 startPos, Vector3 endPos, float width, float step)
{
Mesh mesh = new Mesh();
List<Vector3> listMidVertex = new List<Vector3>();
List<Vector3> listLeftVertex = new List<Vector3>();
List<Vector3> listRightVertex = new List<Vector3>();
List<Vector3> listNormal = new List<Vector3>();
Vector3 curveDir = endPos - startPos;
float pathLen = curveDir.magnitude;
curveDir = curveDir / pathLen;
int count = (int)(pathLen / step);
Ray ray;
float heightOff = 5f;
RaycastHit hitInfo;
float rayLength = 20;
int layerMask = -1;
for (int i = 0; i < count; ++i)
{
ray = new Ray(startPos + i * step * curveDir + Vector3.up * heightOff, -Vector3.up);
if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
{
listMidVertex.Add(hitInfo.point);
listNormal.Add(hitInfo.normal);
}
}
Vector3 averageNormal = Vector3.zero;
Vector3 origin = (startPos + endPos) / 2;
Vector3 originOffUp = origin + Vector3.up * 5;
for (int i = 0; i < count; ++i)
{
averageNormal = (averageNormal * i + listNormal[i]) / (i + 1);
listNormal[i] = averageNormal;
Vector3 dir = Vector3.Cross(listNormal[i], curveDir).normalized;
Vector3 leftPos = listMidVertex[i] - dir * width;
Vector3 rightPos = listMidVertex[i] + dir * width;
ray = new Ray(originOffUp, leftPos - originOffUp);
if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
{
listLeftVertex.Add(hitInfo.point);
}
else
{
break;
}
ray = new Ray(originOffUp, rightPos - originOffUp);
if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
{
listRightVertex.Add(hitInfo.point);
}
else
{
break;
}
}
int totalPointCount = Mathf.Min(listLeftVertex.Count, listRightVertex.Count);
if(totalPointCount < 1)
{
return mesh;
}
Vector3[] vertices = new Vector3[totalPointCount * 3];
Vector3[] normals = new Vector3[totalPointCount * 3];
Vector2[] UVS = new Vector2[totalPointCount * 3];
int[] triangles = new int[(totalPointCount - 1) * 12];
Vector3 curveMidPos = (listMidVertex[0] + listMidVertex[listMidVertex.Count - 1]) / 2;
meshFilter.transform.position = curveMidPos;
//UV: 在0,1之间表示放大了图片(0.2, tmp)(0.8,tmp), 小于0, 大于1表示缩小了图片(-0.8,tmp) (1,8,tmp);
for (int i = 0; i < totalPointCount * 3; i += 3)
{
vertices[i] = listMidVertex[i / 3] - curveMidPos;
vertices[i + 1] = listLeftVertex[i / 3] - curveMidPos;
vertices[i + 2] = listRightVertex[i / 3] - curveMidPos;
normals[i + 2] = normals[i + 1] = normals[i] = listNormal[i / 3];
float temp = 1 - (float)(i / 3) / (float)(totalPointCount - 1);
UVS[i] = new Vector2(0.5f, temp);
UVS[i + 1] = new Vector2(0, temp);
UVS[i + 2] = new Vector2(1, temp);
}
//按逆时针设置三角形中的顶点缩影,否则,就会显示在反面
for (int i = 0; i < (totalPointCount - 1) * 12; i += 12)
{
triangles[i] = i / 4;
triangles[i + 1] = triangles[i] + 4;
triangles[i + 2] = triangles[i] + 3;
triangles[i + 3] = triangles[i];
triangles[i + 4] = triangles[i] + 1;
triangles[i + 5] = triangles[i] + 4;
triangles[i + 6] = triangles[i];
triangles[i + 7] = triangles[i] + 5;
triangles[i + 8] = triangles[i] + 2;
triangles[i + 9] = triangles[i];
triangles[i + 10] = triangles[i] + 3;
triangles[i + 11] = triangles[i] + 5;
}
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = UVS;
mesh.triangles = triangles;
return mesh;
}
没有中间点,只存在左右点的mesh绘制代码
public static Mesh CreateRoughCurveMesh(MeshFilter meshFilter, Vector3 startPos, Vector3 endPos, float width, float step)
{
Mesh mesh = new Mesh();
List<Vector3> listMidVertex = new List<Vector3>();
List<Vector3> listLeftVertex = new List<Vector3>();
List<Vector3> listRightVertex = new List<Vector3>();
List<Vector3> listNormal = new List<Vector3>();
Vector3 curveDir = endPos - startPos;
float pathLen = curveDir.magnitude;
curveDir = curveDir / pathLen;
int count = (int)(pathLen / step);
Ray ray;
float heightOff = 5f;
RaycastHit hitInfo;
float rayLength = 20;
int layerMask = -1;
for (int i = 0; i < count; ++i)
{
ray = new Ray(startPos + i * step * curveDir + Vector3.up * heightOff, -Vector3.up);
if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
{
listMidVertex.Add(hitInfo.point);
listNormal.Add(hitInfo.normal);
}
}
Vector3 averageNormal = Vector3.zero;
Vector3 origin = (startPos + endPos) / 2;
Vector3 originOffUp = origin + Vector3.up * 5;
for (int i = 0; i < count; ++i)
{
averageNormal = (averageNormal * i + listNormal[i]) / (i + 1);
listNormal[i] = averageNormal;
Vector3 dir = Vector3.Cross(listNormal[i], curveDir).normalized;
Vector3 leftPos = listMidVertex[i] - dir * width;
Vector3 rightPos = listMidVertex[i] + dir * width;
ray = new Ray(originOffUp, leftPos - originOffUp);
if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
{
listLeftVertex.Add(hitInfo.point);
}
else
{
break;
}
ray = new Ray(originOffUp, rightPos - originOffUp);
if (Physics.Raycast(ray, out hitInfo, rayLength, layerMask))
{
listRightVertex.Add(hitInfo.point);
}
else
{
break;
}
}
int totalPointCount = Mathf.Min(listLeftVertex.Count, listRightVertex.Count);
if (totalPointCount < 1)
{
return mesh;
}
Vector3[] vertices = new Vector3[totalPointCount * 2];
Vector3[] normals = new Vector3[totalPointCount * 2];
Vector2[] UVS = new Vector2[totalPointCount * 2];
int[] triangles = new int[(totalPointCount - 1) * 6];
Vector3 curveMidPos = (listMidVertex[0] + listMidVertex[listMidVertex.Count - 1]) / 2;
meshFilter.transform.position = curveMidPos;
//UV: 在0,1之间表示放大了图片(0.2, tmp)(0.8,tmp), 小于0, 大于1表示缩小了图片(-0.8,tmp) (1,8,tmp);
for (int i = 0; i < totalPointCount * 2; i += 2)
{
vertices[i] = listLeftVertex[i / 2] - curveMidPos;
vertices[i + 1] = listRightVertex[i / 2] - curveMidPos;
normals[i + 1] = normals[i] = listNormal[i / 2];
float temp = 1 - (float)(i / 2) / (float)(totalPointCount - 1);
UVS[i] = new Vector2(0, temp);
UVS[i + 1] = new Vector2(1, temp);
}
//按逆时针设置三角形中的顶点缩影,否则,就会显示在反面
for (int i = 0; i < (totalPointCount - 1) * 6; i += 6)
{
triangles[i] = i / 3;
triangles[i + 1] = triangles[i] + 2;
triangles[i + 2] = triangles[i] + 3;
triangles[i + 3] = triangles[i];
triangles[i + 4] = triangles[i] + 3;
triangles[i + 5] = triangles[i] + 1;
}
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = UVS;
mesh.triangles = triangles;
return mesh;
}