您的位置:首页 > 移动开发 > Unity3D

Unity中连线

2013-12-04 20:17 218 查看
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

如有不对的地方,还请指教,呵呵!



-----------------------------------------------------------------------

本文是移植与梦想之家工作室(博客园)/article/6226728.html,希望我们的工作室对大家的学习有所帮助,并希望大家多多指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: