尽管unity3D中直接有模块画圆柱体,但画圆面仍旧需要自己使用mesh来绘制。使用mesh画图一般分为四个步骤。
1.顶点
2.三角形
3.UV
4.负载属性与mesh
自己绘制一个简单的平面代码如下:
Mesh Createmeshp(float radius, float Height)
{
//vertices:
int p_vertices_count = 4;
Vector3[] p_vertices = new Vector3[p_vertices_count];
p_vertices[0] = new Vector3(-radius, -Height / 2, radius);
p_vertices[1] = new Vector3(-radius, Height / 2, radius);
p_vertices[2] = new Vector3(radius, -Height / 2, radius);
p_vertices[3] = new Vector3(radius, Height / 2, radius);
//triangles
int[] p_triangles = new int[6];
p_triangles[0] = 0;
p_triangles[1] = 1;
p_triangles[2] = 2;
p_triangles[3] = 3;
p_triangles[4] = 2;
p_triangles[5] = 1;
//uv:
Vector2[] p_uvs = new Vector2[4];
float p_uvSetup = 1.0f ;
p_uvs[0] = new Vector2(p_uvSetup * 0, 1);
p_uvs[1] = new Vector2(p_uvSetup * 0, 0);
p_uvs[2] = new Vector2(p_uvSetup * 1, 1);
p_uvs[3] = new Vector2(p_uvSetup * 1, 0);
//负载属性与mesh
Mesh mesh = new Mesh();
mesh.vertices = p_vertices;
mesh.triangles = p_triangles;
mesh.uv = p_uvs;
return mesh;
}
绘制结果如下图所示:
而圆柱面和平面最大的区别就是面是首尾相连的,所以在画三角形时应该分别考虑连续的部分和首尾相连的部分,比如考虑由四个平面组成的首尾相连的长方体侧面,他们可以按如下代码绘制:
Mesh Createmesh(float radius, float Height)
{
int s_vertices_count = 8;
Vector3[] s_vertices = new Vector3[s_vertices_count];
s_vertices[0] = new Vector3(-radius, -Height / 2, -radius);
s_vertices[1] = new Vector3(-radius, Height / 2, -radius);
s_vertices[2] = new Vector3(-radius, -Height / 2, radius);
s_vertices[3] = new Vector3(-radius, Height / 2, radius);
s_vertices[4] = new Vector3(radius, -Height / 2, radius);
s_vertices[5] = new Vector3(radius, Height / 2, radius);
s_vertices[6] = new Vector3(radius, -Height / 2, -radius);
s_vertices[7] = new Vector3(radius, Height / 2, -radius);
//triangles
int tri_num = 8;
int tri_cout = tri_num * 3;
int[] s_triangles = new int[tri_cout];
for (int i = 0, vi = 0; i < tri_cout - 6; i += 6, vi += 2)
{
s_triangles[i] = vi;
s_triangles[i + 1] = vi + 1;
s_triangles[i + 2] = vi + 2;
s_triangles[i + 3] = vi + 3;
s_triangles[i + 4] = vi + 2;
s_triangles[i + 5] = vi + 1;
}
s_triangles[tri_cout - 6] = 6;
s_triangles[tri_cout - 5] = 7;
s_triangles[tri_cout - 4] = 0;
s_triangles[tri_cout - 3] = 1;
s_triangles[tri_cout - 2] = 0;
s_triangles[tri_cout - 1] = 7;
//uv:
Vector2[] s_uvs = new Vector2[s_vertices_count];
float s_uvSetup = 1.0f / 4;
int iduv = 0;
for (int i = 0; i < s_vertices_count; i = i + 2)
{
s_uvs[i] = new Vector2(s_uvSetup * iduv, 1);
s_uvs[i + 1] = new Vector2(s_uvSetup * iduv, 0);
iduv++;
}
//负载属性与mesh
Mesh mesh = new Mesh();
mesh.vertices = s_vertices;
mesh.triangles = s_triangles;
mesh.uv = s_uvs;
return mesh;
}
结果显示如下:
由于圆柱面地面是个圆,还得需要按照一定的规律来计算圆周上的各点
Mesh CreateMesh(float radius, int segments, float Height)
{
//vertices:
int vertices_count = Segments * 2;
Vector3[] vertices = new Vector3[vertices_count];
//vertices[0] = Vector3.zero;
float angledegree = 360.0f;
float angleRad = Mathf.Deg2Rad * angledegree;
float angleCur = angleRad;
float angledelta = angleRad / Segments;
for (int i = 0; i < vertices_count; i++)
{
float cosA = Mathf.Cos(angleCur);
float sinA = Mathf.Sin(angleCur);
vertices[i] = new Vector3(Radius * cosA, Height / 2, Radius * sinA);
i++;
vertices[i] = new Vector3(Radius * cosA, -Height / 2, Radius * sinA);
angleCur -= angledelta;
}
//triangles
int triangle_count = segments * 3 * 2;
int[] triangles = new int[triangle_count];
int vert = 0;
int idx = 0;
for (int i = 0; i < segments - 1; i++) //因为该案例分割了60个三角形,故最后一个索引顺序应该是:0 60 1;所以需要单独处理
{
triangles[idx++] = vert + 1;
triangles[idx++] = vert;
triangles[idx++] = vert + 3;
triangles[idx++] = vert;
triangles[idx++] = vert + 2;
triangles[idx++] = vert + 3;
vert += 2;
}
triangles[triangle_count - 6] = vertices_count - 1;
triangles[triangle_count - 5] = vertices_count - 2;
triangles[triangle_count - 4] = 1;
triangles[triangle_count - 3] = vertices_count - 2;
triangles[triangle_count - 2] = 0;
triangles[triangle_count - 1] = 1; //为了完成闭环,将最后一个三角形单独拎出来
//uv:
Vector2[] uvs = new Vector2[vertices_count];
float uvSetup = 1.0f / Segments;
int iduv = 0;
for (int i = 0; i < vertices_count; i = i + 2)
{
uvs[i] = new Vector2(uvSetup * iduv, 1);
uvs[i + 1] = new Vector2(uvSetup * iduv, 0);
iduv++;
}
//负载属性与mesh
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
return mesh;
}
结果如下:
侧面
俯视
附整体代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour
{
public float Radius = 10f; //半径
public int Segments = 600; //分割数
public float Height = 2; ///3.1415926f;
private MeshFilter meshFilter;
void Start()
{
//Debug.Log("hello unity: ");
meshFilter = GetComponent<MeshFilter>();
//圆柱,长方体,平面
meshFilter.mesh = CreateMesh(Radius, Segments,Height);
//meshFilter.mesh = Createmesh(Radius, Height);
//meshFilter.mesh = Createmeshp(Radius, Height);
}
Mesh CreateMesh(float radius, int segments, float Height)
{
//vertices:
int vertices_count = Segments * 2;
Vector3[] vertices = new Vector3[vertices_count];
//vertices[0] = Vector3.zero;
float angledegree = 360.0f;
float angleRad = Mathf.Deg2Rad * angledegree;
float angleCur = angleRad;
float angledelta = angleRad / Segments;
for (int i = 0; i < vertices_count; i++)
{
float cosA = Mathf.Cos(angleCur);
float sinA = Mathf.Sin(angleCur);
vertices[i] = new Vector3(Radius * cosA, Height / 2, Radius * sinA);
i++;
vertices[i] = new Vector3(Radius * cosA, -Height / 2, Radius * sinA);
angleCur -= angledelta;
}
//triangles
int triangle_count = segments * 3 * 2;
int[] triangles = new int[triangle_count];
int vert = 0;
int idx = 0;
for (int i = 0; i < segments - 1; i++) //因为该案例分割了60个三角形,故最后一个索引顺序应该是:0 60 1;所以需要单独处理
{
triangles[idx++] = vert + 1;
triangles[idx++] = vert;
triangles[idx++] = vert + 3;
triangles[idx++] = vert;
triangles[idx++] = vert + 2;
triangles[idx++] = vert + 3;
vert += 2;
}
triangles[triangle_count - 6] = vertices_count - 1;
triangles[triangle_count - 5] = vertices_count - 2;
triangles[triangle_count - 4] = 1;
triangles[triangle_count - 3] = vertices_count - 2;
triangles[triangle_count - 2] = 0;
triangles[triangle_count - 1] = 1; //为了完成闭环,将最后一个三角形单独拎出来
//uv:
Vector2[] uvs = new Vector2[vertices_count];
float uvSetup = 1.0f / Segments;
int iduv = 0;
for (int i = 0; i < vertices_count; i = i + 2)
{
uvs[i] = new Vector2(uvSetup * iduv, 1);
uvs[i + 1] = new Vector2(uvSetup * iduv, 0);
iduv++;
}
//负载属性与mesh
Mesh mesh = new Mesh();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
return mesh;
}
Mesh Createmesh(float radius, float Height)
{
int s_vertices_count = 8;
Vector3[] s_vertices = new Vector3[s_vertices_count];
s_vertices[0] = new Vector3(-radius, -Height / 2, -radius);
s_vertices[1] = new Vector3(-radius, Height / 2, -radius);
s_vertices[2] = new Vector3(-radius, -Height / 2, radius);
s_vertices[3] = new Vector3(-radius, Height / 2, radius);
s_vertices[4] = new Vector3(radius, -Height / 2, radius);
s_vertices[5] = new Vector3(radius, Height / 2, radius);
s_vertices[6] = new Vector3(radius, -Height / 2, -radius);
s_vertices[7] = new Vector3(radius, Height / 2, -radius);
//triangles
int tri_num = 8;
int tri_cout = tri_num * 3;
int[] s_triangles = new int[tri_cout];
for (int i = 0, vi = 0; i < tri_cout - 6; i += 6, vi += 2)
{
s_triangles[i] = vi;
s_triangles[i + 1] = vi + 1;
s_triangles[i + 2] = vi + 2;
s_triangles[i + 3] = vi + 3;
s_triangles[i + 4] = vi + 2;
s_triangles[i + 5] = vi + 1;
}
s_triangles[tri_cout - 6] = 6;
s_triangles[tri_cout - 5] = 7;
s_triangles[tri_cout - 4] = 0;
s_triangles[tri_cout - 3] = 1;
s_triangles[tri_cout - 2] = 0;
s_triangles[tri_cout - 1] = 7;
//uv:
Vector2[] s_uvs = new Vector2[s_vertices_count];
float s_uvSetup = 1.0f / 4;
int iduv = 0;
for (int i = 0; i < s_vertices_count; i = i + 2)
{
s_uvs[i] = new Vector2(s_uvSetup * iduv, 1);
s_uvs[i + 1] = new Vector2(s_uvSetup * iduv, 0);
iduv++;
}
//负载属性与mesh
Mesh mesh = new Mesh();
mesh.vertices = s_vertices;
mesh.triangles = s_triangles;
mesh.uv = s_uvs;
return mesh;
}
Mesh Createmeshp(float radius, float Height)
{
int p_vertices_count = 4;
Vector3[] p_vertices = new Vector3[p_vertices_count];
p_vertices[0] = new Vector3(-radius, -Height / 2, radius);
p_vertices[1] = new Vector3(-radius, Height / 2, radius);
p_vertices[2] = new Vector3(radius, -Height / 2, radius);
p_vertices[3] = new Vector3(radius, Height / 2, radius);
//triangles
int[] p_triangles = new int[6];
p_triangles[0] = 0;
p_triangles[1] = 1;
p_triangles[2] = 2;
p_triangles[3] = 3;
p_triangles[4] = 2;
p_triangles[5] = 1;
//uv:
Vector2[] p_uvs = new Vector2[4];
float p_uvSetup = 1.0f ;
p_uvs[0] = new Vector2(p_uvSetup * 0, 1);
p_uvs[1] = new Vector2(p_uvSetup * 0, 0);
p_uvs[2] = new Vector2(p_uvSetup * 1, 1);
p_uvs[3] = new Vector2(p_uvSetup * 1, 0);
//负载属性与mesh
Mesh mesh = new Mesh();
mesh.vertices = p_vertices;
mesh.triangles = p_triangles;
mesh.uv = p_uvs;
return mesh;
}
// Update is called once per frame
void Update()
{
}
}