Unity Mesh(四) Mesh 平面圖形的貼圖
阿新 • • 發佈:2019-02-12
前面都講了怎麼畫,沒有寫怎麼貼圖,上一篇提到了法線,今天這篇會說說平面圖形的貼圖。
為了更好的觀察,我們使用這張圖片來進行貼圖(可以右擊儲存):
一、三角形貼圖
三角形的貼圖是最簡單的,因為我們畫的三角形就簡單,直接根據點來選取:
首先說下貼圖的座標系:如下圖
然後看我們的三角形的座標:
理論上,我們直接捨去三角形Vertices座標的z就可以了,然後貼圖就應該是圖中的黃色三角形內的區域,下面我們驗證下:
程式碼如下:
void DrawTriangle()
{
gameObject.AddComponent<MeshFilter>();
gameObject.AddComponent<MeshRenderer>();
gameObject.GetComponent<MeshRenderer>().material = mat;
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
//設定頂點
mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0) };
mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1) };
mesh.triangles = new int[] { 0, 1, 2 };
}
結果如圖:
可以看到和我們預想的一樣。
二、正方形貼圖
正方形的貼圖就比較簡單了,直接是整張圖片,就是把畫正方形的四個點的z值捨去變成二維座標就可以了。
程式碼如下:
void DrawSquare()
{
gameObject.AddComponent<MeshFilter>();
gameObject.AddComponent<MeshRenderer>();
gameObject.GetComponent<MeshRenderer>().material = mat;
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
mesh.vertices = new Vector3[] { new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 1, 0), new Vector3(1, 0, 0) };
mesh.triangles = new int[]
{ 0, 1, 2,
0, 2, 3
};
mesh.uv = new Vector2[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) };
}
結果如圖:
三、圓的貼圖
圓的貼圖,稍微複雜一點,涉及到座標軸的轉換,我們先說下邏輯思路:從圖片的講解中就可以看到我們隊x,y的處理,就是我們指令碼中需要對我們的座標進行的處理,好了程式碼如下:
#region 畫圓
/// <summary>
/// 畫圓
/// </summary>
/// <param name="radius">圓的半徑</param>
/// <param name="segments">圓的分割數</param>
/// <param name="centerCircle">圓心得位置</param>
void DrawCircle(float radius, int segments, Vector3 centerCircle)
{
gameObject.AddComponent<MeshFilter>();
gameObject.AddComponent<MeshRenderer>();
gameObject.GetComponent<MeshRenderer>().material = mat;
//頂點
Vector3[] vertices = new Vector3[segments + 1];
vertices[0] = centerCircle;
float deltaAngle = Mathf.Deg2Rad * 360f / segments;
float currentAngle = 0;
for (int i = 1; i < vertices.Length; i++)
{
float cosA = Mathf.Cos(currentAngle);
float sinA = Mathf.Sin(currentAngle);
vertices[i] = new Vector3(cosA * radius + centerCircle.x, sinA * radius + centerCircle.y, 0);
currentAngle += deltaAngle;
}
//三角形
int[] triangles = new int[segments * 3];
for (int i = 0, j = 1; i < segments * 3 - 3; i += 3, j++)
{
triangles[i] = 0;
triangles[i + 1] = j + 1;
triangles[i + 2] = j;
}
triangles[segments * 3 - 3] = 0;
triangles[segments * 3 - 2] = 1;
triangles[segments * 3 - 1] = segments;
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
uvs[i] = new Vector2(vertices[i].x / radius / 2 + 0.5f, vertices[i].y / radius / 2 + 0.5f);
}
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
}
#endregion
結果如圖:
是不是跟我們預想的一樣,哈哈。
四、圓環的貼圖
圓環的做法和圓的貼圖取法是一樣的:
不過我們需要取的半徑是內圓的半徑,不然就會重複貼圖了。
程式碼如下:
#region 畫圓環
/// <summary>
/// 畫圓環
/// </summary>
/// <param name="radius">圓半徑</param>
/// <param name="innerRadius">內圓半徑</param>
/// <param name="segments">圓的分個數</param>
/// <param name="centerCircle">圓心座標</param>
void DrawRing(float radius, float innerRadius, int segments, Vector3 centerCircle)
{
gameObject.AddComponent<MeshFilter>();
gameObject.AddComponent<MeshRenderer>();
gameObject.GetComponent<MeshRenderer>().material = mat;
//頂點
Vector3[] vertices = new Vector3[segments * 2];
float deltaAngle = Mathf.Deg2Rad * 360f / segments;
float currentAngle = 0;
for (int i = 0; i < vertices.Length; i += 2)
{
float cosA = Mathf.Cos(currentAngle);
float sinA = Mathf.Sin(currentAngle);
vertices[i] = new Vector3(cosA * innerRadius + centerCircle.x, sinA * innerRadius + centerCircle.y, 0);
vertices[i + 1] = new Vector3(cosA * radius + centerCircle.x, sinA * radius + centerCircle.y, 0);
currentAngle += deltaAngle;
}
//三角形
int[] triangles = new int[segments * 6];
for (int i = 0, j = 0; i < segments * 6; i += 6, j += 2)
{
triangles[i] = j;
triangles[i + 1] = (j + 1) % vertices.Length;
triangles[i + 2] = (j + 3) % vertices.Length;
triangles[i + 3] = j;
triangles[i + 4] = (j + 3) % vertices.Length;
triangles[i + 5] = (j + 2) % vertices.Length;
}
Vector2[] uvs = new Vector2[vertices.Length];
for (int i = 0; i < vertices.Length; i++)
{
uvs[i] = new Vector2(vertices[i].x / innerRadius / 2 + 0.5f, vertices[i].y / innerRadius / 2 + 0.5f);
}
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.uv = uvs;
}
#endregion
結果如圖:
就是取得貼圖中的圓環部分。
五、總結
總得來說,平面圖形的貼圖還是比好好理解的,你也可以試試其他圖形的貼圖
最後給出所有貼圖的合照,哈哈
快過年了,新年快樂!