Unity3D創(chuàng)建圓柱體的方法
看到這篇文章你可能好奇unity自帶圓柱體組件,直接就可以生成,為什么我們還要用代碼生成。其實(shí)是最近領(lǐng)導(dǎo)對項(xiàng)目有一個(gè)要求,就是我們要在自寫編輯器內(nèi)操作圓管,也就是圓柱體。功能類似3DMax里的拉伸管線。剛開始看到這個(gè)要求我內(nèi)心是拒絕的,mmp我是unity程序員不是圖像學(xué)程序員啊,這看著有點(diǎn)底層啊。但是心想,這也是自我學(xué)習(xí)提升的機(jī)會(huì),于是我就給領(lǐng)導(dǎo)個(gè)面子將它實(shí)現(xiàn)吧。我們知道如果想像3Dmax里那樣操作管線,就必須用代碼創(chuàng)建圓柱體并用代碼控制他的頂點(diǎn)位置才能實(shí)現(xiàn)我們的需求。所以第一步就是用代碼創(chuàng)建我們需要的圓柱體。實(shí)現(xiàn)的效果如下:

其實(shí)之前我自己嘗試了解創(chuàng)建立方體的代碼,看著很簡單,其實(shí)也不簡單,主要是對頂點(diǎn),以及對應(yīng)組成三角面頂點(diǎn)順序的設(shè)置。我在網(wǎng)上搜到一篇自寫圓柱體的代碼,看著不錯(cuò),直接復(fù)制來了,但是他提供的少兩個(gè)面。所以需要我們自己去補(bǔ)上這個(gè)面。然后很重要的一點(diǎn)是兩個(gè)面的交點(diǎn)不可以共用,必須再添加一次,因?yàn)樯婕暗椒ň€的問題。
//圓柱體是由兩個(gè)圓和一個(gè)長方形組成的 先輸入長方形的頂點(diǎn) 然后在輸入圓頂點(diǎn)
private void UpdateMesh(Mesh mesh,int edg_x, int edg_y, float rad, float len)
{
edg_x = Mathf.Max(2, edg_x);//保證最低2個(gè)邊
edg_y = Mathf.Max(2, edg_y);
int _deglen = (edg_x +1)*edg_y;//長方體
int totalcount = _deglen + (1 + edg_x + 1) * 2; //加兩個(gè)圓
Vector3[] normals = new Vector3[totalcount];
Vector3[] verts = new Vector3[totalcount];
Vector2[] uvs = new Vector2[totalcount];
int[] trians = new int[edg_x * edg_y*6];
float reg = 6.28318f / edg_x;
float _len = len / (edg_y - 1);
for (int y = 0; y < edg_y; y++)
for (int x = 0; x < edg_x + 1; x++)//多一個(gè)邊來保存UV值
{
int i = x + y * (edg_x + 1);
verts[i] = new Vector3(Mathf.Sin((reg * (x % edg_x)) % 6.28318f) * rad, Mathf.Cos((reg * (x % edg_x)) % 6.28318f) * rad, rightPos + y * _len);//計(jì)算頂點(diǎn)坐標(biāo)
normals[i] = new Vector3(verts[i].x, verts[i].y, 0);//計(jì)算法線方向
int id = x % (edg_x + 1) * 6 + y * edg_x * 6;
if (x < edg_x + 1 && y < edg_y - 1 && (id + 5) < trians.Length)//計(jì)算頂點(diǎn)數(shù)組
{
if(length>0)
{
trians[id] = i;
trians[id + 1] = trians[id + 4] = i + edg_x + 1;
trians[id + 2] = trians[id + 3] = i + 1;
trians[id + 5] = i + edg_x + 2;
}
else
{
trians[id] = i;
trians[id + 1] = trians[id + 3] = i + 1;
trians[id + 2]= trians[id + 5]=i + edg_x + 1;
trians[id + 4] = i + edg_x + 2;
}
}
//if (edg_x != 2)//計(jì)算UV,考慮到2個(gè)邊的情況
// uvs[i] = new Vector2(x == edg_x ? 1f : quaduvStep.x * x, y == edg_y - 1 ? (2*rad+len)/totalLen : quaduvStep.y * y);
//else
// uvs[i] = new Vector2(x % edg_x, y == edg_y - 1 ? (2 * rad + len) / totalLen : quaduvStep.y * y);
}
int maxId = edg_x * (edg_y - 1) * 6;
verts[_deglen] = new Vector3(0,0,rightPos);
normals[_deglen] = -Vector3.forward;
//uvs[_deglen] = new Vector2(0.5f, (rad) / totalLen);
//原點(diǎn)一面
for (int x = 0; x < edg_x+1 ; x++)
{
verts[_deglen + 1 + x] = new Vector3(Mathf.Sin((reg * (x % edg_x)) % 6.28318f) * rad, Mathf.Cos((reg * (x % edg_x)) % 6.28318f) * rad, rightPos);
normals[_deglen + 1 + x] = -Vector3.forward;
if (x == edg_x) continue;
if(length>0)
{
trians[3 * x + maxId] = _deglen;
trians[3 * x + 1 + maxId] = _deglen + 1 + x;
trians[3 * x + 2 + maxId] = _deglen + 2 + x;
}
else
{
trians[3 * x + maxId] = _deglen;
trians[3 * x + 1 + maxId] = _deglen + 2 + x;
trians[3 * x + 2 + maxId] = _deglen + 1 + x;
}
}
//遠(yuǎn)點(diǎn)一面
maxId += 3 * edg_x;
verts[_deglen + 2 + edg_x] = new Vector3(0, 0, leftPos);
normals[_deglen + 2 + edg_x] = Vector3.forward;
//uvs[_deglen + 1] = new Vector2(0.5f, (3 * rad + len) / totalLen);
for (int x = 0; x < edg_x+1; x++)
{
verts[1 + x+edg_x+2+ _deglen] =new Vector3(Mathf.Sin((reg * (x % edg_x)) % 6.28318f) * rad, Mathf.Cos((reg * (x % edg_x)) % 6.28318f) * rad,leftPos);
normals[1 + x + edg_x + 2 + _deglen] = Vector3.forward;
if (x == edg_x) continue;
if (length > 0)
{
trians[3 * x + maxId] = _deglen + 2 + edg_x;
trians[3 * x + 1 + maxId] = _deglen + 2 + edg_x + x + 2;
trians[3 * x + 2 + maxId] = _deglen + 2 + edg_x + x + 1;
}
else
{
trians[3 * x + maxId] = _deglen + 2 + edg_x;
trians[3 * x + 1 + maxId] = _deglen + 2 + edg_x + x + 1;
trians[3 * x + 2 + maxId] = _deglen + 2 + edg_x + x + 2;
}
}
mesh.Clear();
mesh.vertices = verts;
mesh.triangles = trians;
//mesh.uv = uvs;
mesh.normals = normals;
mesh.RecalculateBounds();
}
其實(shí)看代碼會(huì)發(fā)現(xiàn)這個(gè)圓柱體的長度len是由我們自己聲明的變量leftPos-rightPos獲得的。即length=len=leftPos-rightPos。我們可以操作變量leftPos和rightPos來控制圓柱一端的位置以及其長度。當(dāng)我們length<0的時(shí)候,他的三角面頂點(diǎn)繪制順序正好相反,所以需要在代碼塊中判斷下。以上就是對代碼繪制圓柱體的實(shí)現(xiàn)。希望對你有幫助。
相關(guān)文章
WPF自定義MenuItem樣式的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于WPF自定義MenuItem樣式的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用WPF具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Silverlight實(shí)現(xiàn)跑馬燈動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Silverlight實(shí)現(xiàn)跑馬燈動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Unity使用攝像機(jī)實(shí)現(xiàn)望遠(yuǎn)鏡效果
這篇文章主要為大家詳細(xì)介紹了Unity攝使用像機(jī)實(shí)現(xiàn)望遠(yuǎn)鏡效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
C#通過HttpWebRequest發(fā)送帶有JSON Body的POST請求實(shí)現(xiàn)
本文主要介紹了C#通過HttpWebRequest發(fā)送帶有JSON Body的POST請求實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
c#使用Unity粒子實(shí)現(xiàn)炮塔發(fā)射系統(tǒng)
Unity自帶粒子發(fā)射器、動(dòng)畫器、渲染器各兩種,利用Unity的粒子系統(tǒng)制作一個(gè)炮塔發(fā)射系統(tǒng),了解粒子系統(tǒng),必須先了解每一個(gè)屬性都代表了什么,之后才能根據(jù)這些原理來調(diào)整出自己滿意的效果2022-04-04
基于C#實(shí)現(xiàn)的屏幕指定區(qū)域截屏代碼
這篇文章主要介紹了C#實(shí)現(xiàn)的屏幕指定區(qū)域截屏代碼,有需要的朋友可以參考一下2014-01-01
利用C#版OpenCV實(shí)現(xiàn)圓心求取實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于如何利用C#版OpenCV實(shí)現(xiàn)圓心求取的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05

