-
今天我們來(lái)實(shí)現(xiàn)一個(gè)圓形Image桂肌,如下圖。(哈永淌,這次其實(shí)不是畫雷達(dá)圖了崎场,而是畫圓形Icon,不過其原理和之前的雷達(dá)圖是一樣的遂蛀,而且這里用到了前2篇沒講到的UV谭跨。所以這里列為這個(gè)系列的第三篇!)
圓形Icon.png 實(shí)現(xiàn)步驟
因?yàn)槲覀兪窃谠璉mage上進(jìn)行修改。所以這里新建一個(gè)腳本PolygonImage繼承至Image.
為啥不叫CirecleImage(圓形Image)李滴,而是叫PolygonImage(多邊形Image)呢螃宙。因?yàn)槲覀兤鋵?shí)是把一個(gè)正方形分成正多邊形,當(dāng)邊數(shù)越多所坯,其實(shí)就越趨近圓污呼。比如到正50邊形就很圓了..接著我們定義兩個(gè)屬性:半徑和邊數(shù)
//邊數(shù)
public int lineCount = 5;
//半徑
public float radius = 100;
-
取寬和高較小的一邊的一半,作為半徑
這里因?yàn)镮mage及其基類并不是繼承至UnityEngine.Object包竹。lineCount屬性無(wú)法在Inspector顯示燕酷。
所以這里在update()里讓lineCount等于z坐標(biāo)。所以相當(dāng)于也可以在Inspector里改變邊數(shù)了周瞎。這里只是方便演示苗缩,實(shí)際使用可以注釋掉。
protected void Update()
{
//取邊長(zhǎng)小的一邊作為半徑
radius = Mathf.Min(rectTransform.rect.width,rectTransform.rect.height)/2;
//因?yàn)榛怚mage不繼承UnityEngine.Object,
//所以lineCount無(wú)法序列化,所以這里通過lineCount等于z坐標(biāo)的方式声诸。來(lái)間接實(shí)現(xiàn)在Inspector面板修改邊數(shù)的功能
lineCount = Mathf.Max(3,(int)transform.localPosition.z);
SetAllDirty();
}
4.添加頂點(diǎn)和三角形
這里添加頂點(diǎn)和三角形和之前講的一樣酱讶。唯一不同的就是加入了UV,UV的范圍是0~1彼乌。所以這里我們可以用x坐標(biāo)和寬度的比值泻肯,y坐標(biāo)和高度的比值,再加上0.5偏移慰照。即可算出UV
protected override void OnPopulateMesh(VertexHelper vh)
{
//添加頂點(diǎn)
AddAllVert(vh);
//添加三角形
AddTriangle(vh);
}
private void AddAllVert(VertexHelper vh)
{
vh.Clear();
//計(jì)算每個(gè)角的弧度
float baseRad = (float)Math.PI * 2 / lineCount;
for (int i = 0; i < lineCount; i++)
{
//計(jì)算當(dāng)前的弧度
var rad = i * baseRad;
//根據(jù)弧度換算坐標(biāo)
var x = Mathf.Sin(rad) * radius;
var y = Mathf.Cos(rad) * radius;
Vector2 pos = new Vector2(x,y);
//根據(jù)坐標(biāo)計(jì)算UV
var uvX = x / rectTransform.rect.width + 0.5f;
var uvY = y / rectTransform.rect.height + 0.5f;
var uv = new Vector2(uvX,uvY);
AddVert(vh,pos,uv);
}
}
private void AddVert(VertexHelper vh,Vector2 pos,Vector2 uv)
{
vh.AddVert(pos,color,uv);
}
private void AddTriangle(VertexHelper vh)
{
for (int i = 0; i < lineCount-1; i++)
{
vh.AddTriangle(0,i,i+1);
}
}
這樣就OK了灶挟。回到Unity,新建一個(gè)UI空物體毒租,掛上該腳本稚铣,給上圖標(biāo)。修改Z坐標(biāo)墅垮,即可出現(xiàn)多邊形Image,邊數(shù)越多就越圓惕医。如下圖
多邊形.gif
最后,附上完整代碼
using System;
namespace UnityEngine.UI
{
public class PolygonImage : Image
{
//邊數(shù)
public int lineCount = 5;
//半徑
public float radius = 100;
protected void Update()
{
//取邊長(zhǎng)小的一邊作為半徑
radius = Mathf.Min(rectTransform.rect.width,rectTransform.rect.height)/2;
//因?yàn)榛怚mage不繼承UnityEngine.Object,
//所以lineCount無(wú)法序列化,所以這里通過等于z坐標(biāo)的方式算色。來(lái)間接實(shí)現(xiàn)在Inspector面板修改邊數(shù)的功能
lineCount = Mathf.Max(3,(int)transform.localPosition.z);
SetAllDirty();
}
protected override void OnPopulateMesh(VertexHelper vh)
{
//添加頂點(diǎn)
AddAllVert(vh);
//添加三角形
AddTriangle(vh);
}
private void AddAllVert(VertexHelper vh)
{
vh.Clear();
//計(jì)算每個(gè)角的弧度
float baseRad = (float)Math.PI * 2 / lineCount;
for (int i = 0; i < lineCount; i++)
{
//計(jì)算當(dāng)前的弧度
var rad = i * baseRad;
//根據(jù)弧度換算坐標(biāo)
var x = Mathf.Sin(rad) * radius;
var y = Mathf.Cos(rad) * radius;
Vector2 pos = new Vector2(x,y);
//根據(jù)坐標(biāo)計(jì)算UV
var uvX = x / rectTransform.rect.width + 0.5f;
var uvY = y / rectTransform.rect.height + 0.5f;
var uv = new Vector2(uvX,uvY);
AddVert(vh,pos,uv);
}
}
private void AddVert(VertexHelper vh,Vector2 pos,Vector2 uv)
{
vh.AddVert(pos,color,uv);
}
private void AddTriangle(VertexHelper vh)
{
for (int i = 0; i < lineCount-1; i++)
{
vh.AddTriangle(0,i,i+1);
}
}
}
}
好抬伺,這次就到這里了~