Unity中連線


                                                   Unity中連線

       在unity中做連線的功能,有很多中做法。在這里總結一下,可能還有更好的方法,希望有好的方法就提出來共同進步。(說明:主要是拐直角的線的效果,而不是很華麗的線條效果。其實在虛擬現實項目中,這種效果還是經常用到的,比方說室內的電線連接情況等)

第一種:是unity中的輔助線。Gizmos,是用於在scene視圖下可視化調試或輔助設置。這個就不多說了,在api中有詳細介紹。注意的是:所有的繪制需要在OnDrawGizmos或OnDrawGizmosSelected函數里完成。

第二種:是用LineRenderer,是用於在三維空間繪制自由浮動的線。優點就是可以自適應攝像機,就是始終面對着攝像機。但對於多個拐點時就存在斷線的效果的情況,看上去很不舒服,只能每個點的連接需要兩兩連接效果會好點,但是拐點效果就不是很好。如下圖可以直觀說明。

第三種:是用GL,是底層的圖像庫。這個類進行底層的矩陣變換。常用的方法是GL代碼放在OnPostRender()函數里面。這里講的是如何畫線,所以對於GL畫線來說,不好的地方在於線條太細,無法調整線的粗細。我用GL舉個例子!

      代碼如下:

View Code
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class NewBehaviourScript : MonoBehaviour {
 5     
 6     ArrayList lines=new ArrayList();
 7     // Use this for initialization
 8     void Start () {
 9      MeshFilter meshfilter=GetComponent("MeshFilter") as MeshFilter;
10      Mesh mesh=meshfilter.sharedMesh;
11      Vector3[] vertices=mesh.vertices;
12      int[] triangles=mesh.triangles;
13      for(int i=0;i<triangles.Length/3;i++)
14         {
15             lines.Add(vertices[triangles[i]]);
16             lines.Add(vertices[triangles[i*3+1]]);
17             lines.Add(vertices[triangles[i*3+2]]);
18         }
19     }
20      void OnRenderObject()
21     {
22         if (true)
23         {
24             GL.PushMatrix();
25             GL.MultMatrix(transform.localToWorldMatrix);
26             GL.Begin(GL.LINES);
27             GL.Color(Color.blue);
28             for (int i = 0; i < lines.Count / 3; i++)
29             {
30                 GL.Vertex((Vector3)lines[i * 3]);
31                 GL.Vertex((Vector3)lines[i * 3 + 1]);
32                 GL.Vertex((Vector3)lines[i * 3 + 1]);
33                 GL.Vertex((Vector3)lines[i * 3 + 2]);
34                 GL.Vertex((Vector3)lines[i * 3 + 2]);
35                 GL.Vertex((Vector3)lines[i * 3]);
36             }
37             GL.End();
38             GL.PopMatrix();
39         }
40     }
41     
42 }

 

         解釋一下代碼:

     第一步,獲取模型的所有頂點!

      MeshFilter meshfilter=GetComponent("MeshFilter") as MeshFilter;//查找MeshFilter組建

      Mesh mesh=meshfilter.sharedMesh;//獲取mesh

      Vector3[] vertices=mesh.vertices;//獲取模型的所有頂點

      int[] triangles=mesh.triangles;//三角形的所有頂點的索引(索引是在模型頂點數組的索引)

      for(int i=0;i<triangles.Length;i++)  //有triangles.Length/3個三角形

      {

         lines.Add(vertices[triangles[i]]);

     }

     第二步:繪制模型的頂點之間的網格線

     繪制模型的網格線,就是繪制每個三角形的三條邊,第一步已經把所有的三角形的邊找出來了

,下面就開始繪制了,用GL繪制,那么就必須使用OnRenderObject()方法,

    void OnRenderObject()

    {

            GL.PushMatrix();//壓入矩陣

            /*使用了transform.localToWorldMatrix這個矩陣,上面的頂點沒有進行變換的,還是本地坐標的,在這兒做了轉換!大家要注意的是 transform.localToWorldMatrix變換一個本地坐標的話,那么transform.position並沒有參與變換頂點的工作!在DX和OPENGL中,localToWorldMatrix,那么物體的position都會參加變換的,這一點u3d做的不一樣,呵呵!

          我說的沒有參與變換頂點的工作,是什么意思呢?

         下面我舉個例子!

         transform.localToWorldMatrix*Vector3.forward那么在其它的程序中,是transform.position加上transform的旋轉和縮放對Vector3.forward變換后的值,但是u3d卻沒有這樣做!u3d中transform.localToWorldMatrix*Vector3.forward是用旋轉和縮放對Vector3.forwad做了變換!*/

           //在下面的這一句中明確的告訴大家,transform.position參加了變換!

            GL.MultMatrix(transform.localToWorldMatrix);

          //用線條進行繪制

            GL.Begin(GL.LINES);

           //用藍色進行繪制

            GL.Color(Color.blue);

           //繪制線,兩個點組成一條線段

            for (int i = 0; i < lines.Count / 3; i++)

            {

                GL.Vertex((Vector3)lines[i * 3]);

                GL.Vertex((Vector3)lines[i * 3 + 1]);

                GL.Vertex((Vector3)lines[i * 3 + 1]);

                GL.Vertex((Vector3)lines[i * 3 + 2]);

                GL.Vertex((Vector3)lines[i * 3 + 2]);

                GL.Vertex((Vector3)lines[i * 3]);

            }

           //繪制結束

            GL.End();

          //拋出剛才壓入的矩陣

            GL.PopMatrix();

    }

 

 

 

 

 

第四種:運用Sphere球體和Cylinder圓柱,通過控制縮放來畫線,Sphere處理拐點,使其美觀。

View Code
  1 using UnityEngine;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 
  5 public class DrawLineEX : MonoBehaviour
  6 {
  7     GameObject line;
  8     GameObject corner; 
  9     Vector3[] wayPoint;  
 10     GameObject[] go;               
 11     GameObject lineClone;               
 12 
 13     float offsetScaleH = 0.0f;
 14     float scaleValue;                   
 15     float offsetScaleV = 0.005f;
 16     
 17     public Transform port1;
 18     public Transform port2;
 19 
 20     public void Start()
 21     {
 22         scaleValue = 0.2f;
 23         wayPoint = new Vector3[0];
 24         go = new GameObject[0];
 25         lineClone = new GameObject();
 26         line = (GameObject)Resources.Load("Prefab/Line/Line");
 27         corner = (GameObject)Resources.Load("Prefab/Line/Corner");
 28         
 29         DrawDifLine(port1,port2,1,1,Color.blue);
 30         LineRendererFunc();
 31     }
 32 
 33     //算了7個點,這個可以根據需求來改動自己所需要經過的點。portState參數是用來改變方向的
 34     void DrawDifLine(Transform Selectpoint, Transform Mathpoint, float portState1, float portState2, Color color)
 35     {
 36         wayPoint = new Vector3[7];
 37         wayPoint[0] = Selectpoint.position;
 38 
 39         wayPoint[6] = Mathpoint.position;
 40 
 41         Vector3 position1 = Selectpoint.TransformPoint(new Vector3(0, 0f, 3f * portState1));
 42         wayPoint[1] = position1;
 43 
 44         float y1 = Selectpoint.position.y + 2f;
 45         Vector3 position2 = new Vector3(position1.x, y1, position1.z);
 46         wayPoint[2] = position2;
 47 
 48         Vector3 position3 = Mathpoint.TransformPoint(new Vector3(0, 0f, 3f * portState2));
 49         wayPoint[5] = position3;
 50 
 51         float y2 = Selectpoint.position.y + 2f;
 52         Vector3 position4 = new Vector3(position3.x, y2, position3.z);
 53         wayPoint[4] = position4;
 54 
 55         Vector3 position5 = new Vector3(position4.x, y2, position2.z);
 56         wayPoint[3] = position5;
 57         
 58         DL(color, scaleValue);
 59     }
 60     
 61     //主要的畫法。
 62     void DL(Color lineColor, float lineSize)
 63     {
 64         go = new GameObject[(2 * wayPoint.Length - 3)];
 65         int j;
 66         //draw line
 67         Vector3 centerPos = Vector3.zero;
 68         for (j = 0; j < wayPoint.Length - 1; j++)
 69         {
 70             centerPos = (wayPoint[j] + wayPoint[j + 1]) / 2;
 71             go[j] = (GameObject)Instantiate(line, centerPos, transform.localRotation);
 72             go[j].renderer.material.color = lineColor;
 73 
 74             go[j].transform.parent = lineClone.transform;
 75             go[j].name = "Line" + j + 1;
 76             go[j].transform.up = (go[j].transform.localPosition - wayPoint[j]).normalized;
 77             float distance = Vector3.Distance(wayPoint[j], wayPoint[j + 1]);
 78             go[j].transform.localScale = new Vector3(lineSize, distance / 2 + offsetScaleH, lineSize);
 79         }
 80 
 81         //draw port
 82         for (int i = 1; i < wayPoint.Length - 1; i++)
 83         {
 84             centerPos = wayPoint[i];
 85             go[j + i - 1] = (GameObject)Instantiate(corner, centerPos, transform.localRotation);
 86             go[j + i - 1].renderer.material.color = lineColor;
 87 
 88             go[j + i - 1].name = "Port" + i;
 89             go[j + i - 1].transform.parent = lineClone.transform;
 90             go[j + i - 1].transform.localScale = new Vector3(lineSize, lineSize, lineSize);
 91         }
 92     }
 93     
 94     //GL
 95     public Material mat;
 96     void OnPostRender() {
 97         if (!mat) {
 98             Debug.LogError("Please Assign a material on the inspector");
 99             return;
100         }
101         GL.PushMatrix();
102         mat.SetPass(0);
103         GL.LoadOrtho();
104         GL.Begin(GL.LINES);
105         GL.Color(Color.red);
106         GL.Vertex(Vector3.zero);
107         GL.Vertex(Vector3.one);
108         GL.End();
109         GL.PopMatrix();
110     }
111 
112     //LineRenderer
113     void LineRendererFunc()
114     {
115         GameObject obj = new GameObject();
116         LineRenderer lineRenderer;
117         lineRenderer = obj.AddComponent<LineRenderer>();
118         lineRenderer.useWorldSpace = false;//是否使用世界坐標,true的話,自身坐標將被忽略。
119         lineRenderer.material = new Material(Shader.Find("Particles/Additive"));
120         lineRenderer.SetColors(Color.red, Color.yellow);//設置顏色,一個是起始和終止顏色。
121         lineRenderer.SetVertexCount(7);//設置線段數量,可以根據需求來動態改變,靈活改變。
122 
123         for (int i = 0; i < wayPoint.Length; i++)
124         {
125             lineRenderer.SetPosition(i, wayPoint[i]);
126         }
127     }
128 
129 }

 

代碼如下:對代碼中主要部分做了解釋,如果有不明白的可以留言或者在api中查到。

 

第五種:用Vectrosity插件,這個插件是基於lineRenderer的,是一個很好的插件對於畫線來說。后續中。。。。。

源碼:http://www.cnblogs.com/alongu3d/admin/Files.aspx

如有不對的地方,還請指教,呵呵!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM