Skip to main content
 首页 » 资源教程

Unity3D 使用 GL 绘制线条

2016年09月03日 21:13:166360

在前两篇中,我们使用了 Graphics(查看详情)以及 Line Renderer 方法绘制线条(查看详情),这次我们通过 GL 来绘制线条,这种方法与前两种方法相比,效率与性能上面差不多。原文链接:http://www.everyday3d.com/blog/index.php/2010/03/15/3-ways-to-draw-3d-lines-in-unity3d/。

新建立一个 C# 脚本,取名:DrawLinesByGL.cs 代码如下:

001using UnityEngine;
002using System.Collections;
003 
004public class DrawLinesByGL : MonoBehaviour
005{
006    public Shader shader;
007 
008    private static Material m;
009    private GameObject g;
010    private float speed = 100.0f;
011    private Vector3[] lp;
012    private Vector3[] sp;
013    private Vector3 s;
014 
015    private GUIStyle labelStyle;
016    private GUIStyle linkStyle;
017     
018    void Start () {
019        labelStyle = new GUIStyle();
020        labelStyle.normal.textColor = Color.black;
021         
022        linkStyle = new GUIStyle();
023        linkStyle.normal.textColor = Color.blue;
024         
025        m = new Material(shader);
026        g = new GameObject("g");
027        lp = new Vector3[0];
028        sp = new Vector3[0];
029    }
030     
031    void processInput() {
032        float s = speed * Time.deltaTime;
033        if(Input.GetKey(KeyCode.RightShift) || Input.GetKey(KeyCode.LeftShift)) s = s * 0.1f;
034        if(Input.GetKey(KeyCode.UpArrow)) g.transform.Rotate(-s, 0, 0);
035        if(Input.GetKey(KeyCode.DownArrow)) g.transform.Rotate(s, 0, 0);
036        if(Input.GetKey(KeyCode.LeftArrow)) g.transform.Rotate(0, -s, 0);
037        if(Input.GetKey(KeyCode.RightArrow)) g.transform.Rotate(0, s, 0);
038         
039        if(Input.GetKeyDown(KeyCode.C)) {
040            g.transform.rotation = Quaternion.identity;
041            lp = new Vector3[0];
042            sp = new Vector3[0];
043        }
044    }
045     
046    void Update() {
047        processInput();
048         
049        if(Input.GetMouseButton(0)) {
050             
051            Vector3 e = GetNewPoint();
052             
053            if(s != Vector3.zero) {
054                for(int i = 0; i < lp.Length; i += 2) {
055                    float d = Vector3.Distance(lp[i], e);
056                    if(d < 1 && Random.value > 0.9f) sp = AddLine(sp, lp[i], e, false);
057                }
058                 
059                lp = AddLine(lp, s, e, false);
060            }
061             
062            s = e;
063        else {
064            s = Vector3.zero;
065        }
066    }
067 
068    void Update1() {
069        processInput();
070         
071        Vector3 e;
072         
073        if(Input.GetMouseButtonDown(0)) {
074            s = GetNewPoint();
075        }
076         
077        if(Input.GetMouseButton(0)) {
078            e = GetNewPoint();
079            lp = AddLine(lp, s, e, true);
080        }
081 
082        if(Input.GetMouseButtonUp(0)) {
083            e = GetNewPoint();
084            lp = AddLine(lp, s, e, false);
085        }
086    }
087     
088    Vector3[] AddLine(Vector3[] l, Vector3 s, Vector3 e, bool tmp) {
089        int vl = l.Length;
090        if(!tmp || vl == 0) l = resizeVertices(l, 2);
091        else vl -= 2;
092             
093        l[vl] = s;
094        l[vl+1] = e;
095        return l;
096    }
097     
098    Vector3[] resizeVertices(Vector3[] ovs, int ns) {
099        Vector3[] nvs = new Vector3[ovs.Length + ns];
100        for(int i = 0; i < ovs.Length; i++) nvs[i] = ovs[i];
101        return nvs;
102    }
103     
104    Vector3 GetNewPoint() {
105        return g.transform.InverseTransformPoint(
106            Camera.main.ScreenToWorldPoint(
107                new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z * -1.0f)
108            )
109        );
110    }
111 
112    void OnPostRender() {
113        m.SetPass(0);
114        GL.PushMatrix();
115        GL.MultMatrix(g.transform.transform.localToWorldMatrix);
116        GL.Begin( GL.LINES );
117        GL.Color( new Color(0,0,0,0.4f) );
118         
119        for(int i = 0; i < lp.Length; i++) {
120            GL.Vertex3(lp[i].x, lp[i].y, lp[i].z);
121        }
122         
123        GL.Color( new Color(0,0,0,0.1f) );
124         
125        for(int i = 0; i < sp.Length; i++) {
126            GL.Vertex3(sp[i].x, sp[i].y, sp[i].z);
127        }
128         
129        GL.End();
130        GL.PopMatrix();
131    }
132     
133    void OnGUI() {
134        GUI.Label (new Rect (10, 10, 300, 24), "GL. Cursor keys to rotate (with Shift for slow)", labelStyle);
135        int vc = lp.Length + sp.Length;
136        GUI.Label (new Rect (10, 26, 300, 24), "Pushing " + vc + " vertices. 'C' to clear", labelStyle);
137         
138        GUI.Label (new Rect (10, Screen.height - 20, 250, 24), ".Inspired by a demo from ", labelStyle);
139        if(GUI.Button (new Rect (150, Screen.height - 20, 300, 24), "mrdoob", linkStyle)) {
140            Application.OpenURL("http://mrdoob.com/lab/javascript/harmony/");
141        }
142    }
143}

然后把 DrawLinesByGL.cs 组件挂载到 MainCamera 对象上,如图:

Unity3D 使用 GL 绘制线条 资源教程 第1张

运行游戏,最终效果如图:

Unity3D 使用 GL 绘制线条 资源教程 第2张

资源下载地址:点击下载,共下载 95 次。
评论列表暂无评论
发表评论