Unity3D創(chuàng)建圓柱體的方法
看到這篇文章你可能好奇unity自帶圓柱體組件,直接就可以生成,為什么我們還要用代碼生成。其實是最近領導對項目有一個要求,就是我們要在自寫編輯器內(nèi)操作圓管,也就是圓柱體。功能類似3DMax里的拉伸管線。剛開始看到這個要求我內(nèi)心是拒絕的,mmp我是unity程序員不是圖像學程序員啊,這看著有點底層啊。但是心想,這也是自我學習提升的機會,于是我就給領導個面子將它實現(xiàn)吧。我們知道如果想像3Dmax里那樣操作管線,就必須用代碼創(chuàng)建圓柱體并用代碼控制他的頂點位置才能實現(xiàn)我們的需求。所以第一步就是用代碼創(chuàng)建我們需要的圓柱體。實現(xiàn)的效果如下:
其實之前我自己嘗試了解創(chuàng)建立方體的代碼,看著很簡單,其實也不簡單,主要是對頂點,以及對應組成三角面頂點順序的設置。我在網(wǎng)上搜到一篇自寫圓柱體的代碼,看著不錯,直接復制來了,但是他提供的少兩個面。所以需要我們自己去補上這個面。然后很重要的一點是兩個面的交點不可以共用,必須再添加一次,因為涉及到法線的問題。
//圓柱體是由兩個圓和一個長方形組成的 先輸入長方形的頂點 然后在輸入圓頂點
 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);//計算頂點坐標
    normals[i] = new Vector3(verts[i].x, verts[i].y, 0);//計算法線方向
    int id = x % (edg_x + 1) * 6 + y * edg_x * 6;
    if (x < edg_x + 1 && y < edg_y - 1 && (id + 5) < trians.Length)//計算頂點數(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)//計算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);
  //原點一面
  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;
   }
  }
 
 
  //遠點一面
  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();
 }
其實看代碼會發(fā)現(xiàn)這個圓柱體的長度len是由我們自己聲明的變量leftPos-rightPos獲得的。即length=len=leftPos-rightPos。我們可以操作變量leftPos和rightPos來控制圓柱一端的位置以及其長度。當我們length<0的時候,他的三角面頂點繪制順序正好相反,所以需要在代碼塊中判斷下。以上就是對代碼繪制圓柱體的實現(xiàn)。希望對你有幫助。
上一篇:C# Ado.net實現(xiàn)讀取SQLServer數(shù)據(jù)庫存儲過程列表及參數(shù)信息示例
欄 目:C#教程
本文地址:http://www.jygsgssxh.com/a1/C_jiaocheng/4910.html
您可能感興趣的文章
- 01-10winform實現(xiàn)創(chuàng)建最前端窗體的方法
 - 01-10C#動態(tài)創(chuàng)建button的方法
 - 01-10深入淺出23種設計模式
 - 01-10winform創(chuàng)建不規(guī)則窗體的方法
 - 01-10C#動態(tài)創(chuàng)建Access數(shù)據(jù)庫及密碼的方法
 - 01-10C#實現(xiàn)在啟動目錄創(chuàng)建快捷方式的方法
 - 01-10C#創(chuàng)建不規(guī)則窗體的4種方式詳解
 - 01-10Unity3d獲取系統(tǒng)時間
 - 01-10Unity3D獲取當前鍵盤按鍵及Unity3D鼠標、鍵盤的基本操作
 - 01-10C#創(chuàng)建數(shù)據(jù)庫及導入sql腳本的方法
 


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
 - 01-10關于ASP網(wǎng)頁無法打開的解決方案
 - 01-10WinForm限制窗體不能移到屏幕外的方法
 - 01-10WinForm繪制圓角的方法
 - 01-10C#實現(xiàn)txt定位指定行完整實例
 - 01-10WinForm實現(xiàn)仿視頻播放器左下角滾動新
 - 01-10C#停止線程的方法
 - 01-10C#實現(xiàn)清空回收站的方法
 - 01-10C#通過重寫Panel改變邊框顏色與寬度的
 - 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
 
隨機閱讀
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
 - 01-10使用C語言求解撲克牌的順子及n個骰子
 - 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
 - 01-11ajax實現(xiàn)頁面的局部加載
 - 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
 - 04-02jquery與jsp,用jquery
 - 01-10C#中split用法實例總結(jié)
 - 01-10delphi制作wav文件的方法
 - 08-05織夢dedecms什么時候用欄目交叉功能?
 - 08-05DEDE織夢data目錄下的sessions文件夾有什
 


