Unity3D創(chuàng)建圓柱體的方法
看到這篇文章你可能好奇unity自帶圓柱體組件,直接就可以生成,為什么我們還要用代碼生成。其實(shí)是最近領(lǐng)導(dǎo)對項(xiàng)目有一個要求,就是我們要在自寫編輯器內(nèi)操作圓管,也就是圓柱體。功能類似3DMax里的拉伸管線。剛開始看到這個要求我內(nèi)心是拒絕的,mmp我是unity程序員不是圖像學(xué)程序員啊,這看著有點(diǎn)底層啊。但是心想,這也是自我學(xué)習(xí)提升的機(jī)會,于是我就給領(lǐng)導(dǎo)個面子將它實(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)上搜到一篇自寫圓柱體的代碼,看著不錯,直接復(fù)制來了,但是他提供的少兩個面。所以需要我們自己去補(bǔ)上這個面。然后很重要的一點(diǎn)是兩個面的交點(diǎn)不可以共用,必須再添加一次,因?yàn)樯婕暗椒ň€的問題。
//圓柱體是由兩個圓和一個長方形組成的 先輸入長方形的頂點(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個邊 edg_y = Mathf.Max(2, edg_y); int _deglen = (edg_x +1)*edg_y;//長方體 int totalcount = _deglen + (1 + edg_x + 1) * 2; //加兩個圓 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++)//多一個邊來保存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個邊的情況 // 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í)看代碼會發(fā)現(xiàn)這個圓柱體的長度len是由我們自己聲明的變量leftPos-rightPos獲得的。即length=len=leftPos-rightPos。我們可以操作變量leftPos和rightPos來控制圓柱一端的位置以及其長度。當(dāng)我們length<0的時候,他的三角面頂點(diǎn)繪制順序正好相反,所以需要在代碼塊中判斷下。以上就是對代碼繪制圓柱體的實(shí)現(xiàn)。希望對你有幫助。
相關(guān)文章
C#使用post發(fā)送和接收數(shù)據(jù)的方法
這篇文章主要介紹了C#使用post發(fā)送和接收數(shù)據(jù)的方法,涉及C#使用post收發(fā)數(shù)據(jù)的相關(guān)技巧,非常具有實(shí)用價值,需要的朋友可以參考下2015-04-04C#程序最小化到托盤圖標(biāo)操作步驟與實(shí)現(xiàn)代碼
設(shè)置窗體屬性showinTask=false;加notifyicon控件notifyIcon1,為控件notifyIcon1的屬性Icon添加一個icon圖標(biāo);添加窗體最小化事件(首先需要添加事件引用)接下來介紹實(shí)現(xiàn)代碼,感興趣的朋友可以研究下2012-12-12C#實(shí)現(xiàn)打印與打印預(yù)覽功能的思路及代碼
這篇文章主要介紹了C#實(shí)現(xiàn)打印與打印預(yù)覽功能的思路及代碼,有需要的朋友可以參考一下2013-12-12C#實(shí)現(xiàn)可捕獲幾乎所有鍵盤鼠標(biāo)事件的鉤子類完整實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)可捕獲幾乎所有鍵盤鼠標(biāo)事件的鉤子類,以完整實(shí)例形式分析了C#捕獲鍵盤鼠標(biāo)事件的鉤子操作技巧,具有一定參考借鑒價值,需要的朋友可以參考下2016-06-06