Unity中畫線的方法

【前言】

圖形化調試可以加速開發。

例如在戰鬥中,可能需要知道所有單位的仇恨值,如果這些信息全打log的話,很難有直觀感受,

而如果在Scene窗口裏,單位頭頂有一個球,越紅表示仇恨越高,越暗表示仇恨越低,那麼調試起來比打log直觀多了。

 

【一 圖形化調試】

Unity中圖形化調試主要4種

Debug.Draw

Gizmos.Draw

Graphic.DrawMesh

GL

只需在Scene窗口顯示的調試圖像

     一直顯示的 OnDrawGizmos + Gizmos.Draw

     選中顯示的 OnDrawGizmosSelected + Gizmos.Draw

     腳本控制的 Update + Debug.Draw

需要在實際設備屏幕顯示的調試圖像

    Update+Graphic.DrawMesh

    OnRenderObject+GL

 

Graphic.DrawMesh和Debug.Draw   調用一致,都是在Update系裏

Graphic.DrawMesh和GL       顯示類似,都在各個窗口顯示,並且可以設置材質。

四種方式比較

(1)Debug.Draw

=1=一般在Update/Fixed Update/LateUpdate裏調用

=2=只在Scene窗口裏顯示

=3=並且不能設置材質

     void Update()
    {
        Debug.DrawLine (worldPos1, worldPos2,Color.yellow);
    }

 

(2)Gizmos.Draw

=1=在OnDrawGizmos /OnDrawGizmosSelected裏調用

=2=只在Scene窗口裏顯示

=3=並且不能設置材質

    public void OnDrawGizmosSelected() {
        Gizmos.DrawLine(Vector3.zero, new Vector3(0,3f,0));
    }

(3)Graphic.DrawMesh

=1=一般在Update/Fixed Update/LateUpdate裏調用

=2=實際屏幕和Scene窗口都能顯示

=3=可以設置材質

畫Mesh Ok

         void Update()
        {
            Graphics.DrawMesh(mesh, worldPos, worldRotation, material, 0);
        }

(4)GL,

=1=一般在物體的OnRenderObject 或者相機的OnPostRender裏調用

=2=實際屏幕和Scene窗口都能顯示

=3=可以設置材質

一個GL.Begin/GL.End裏的渲染是自動合併的,一般是一個Drawcall

畫一些線,三角可以。用GL.TRIANGLES 顯示整個Mesh的話會超卡。

例:渲染線框

      void OnRenderObject()
    {
        mat.SetPass(0);

         GL.wireframe = true;

         GL.Color (new Color (1,1, 0, 0.8F));
        GL.PushMatrix();
        GL.Begin(GL.TRIANGLES);
        for(int i=0;i<</span>mesh.triangles.Length-2;i+=3)
        {
            GL.Vertex(mesh.vertices[mesh.triangles[i]]);
            GL.Vertex(mesh.vertices[mesh.triangles[i+1]]);
            GL.Vertex(mesh.vertices[mesh.triangles[i+2]]);
        }
        GL.End();
        GL.PopMatrix();

              GL.wireframe = false;
    }

 

 

【二 GL】

GL除了可以用來調試,可以拿來做功能,例如LineRenderer,地格等。

 

GL即Graphics Library。Low-Level Graphics Library。計算matrices,發出類似OpenGL的immediate模式的渲染指令,和其他低級圖像任務。Graphic.DrawMesh()比GL更高效。

GL立即繪製函數只用當前material的設置。因此除非你顯示指定mat,否則mat可以是任何材質。並且GL可能會改變材質。

GL是立即執行的,如果你在Update()裏調用,它們將在相機渲染前執行,相機渲染將會清空屏幕,GL效果將無法看到。

通常GL用法是
在camera上貼腳本,並在OnPostRender()裏執行。
也可以掛在任何GameObject上,在OnRenderObject()裏執行。
或者掛在物體上
注意: 
1.GL的線等基本圖元並沒有uv. 所有是沒有貼圖紋理影射的,shader裏僅僅做的是單色計算或者對之前的影像加以處理。
2.GL所使用的shader裏必須有Cull off指令,否則顯示會變成如下


3. 如果是線,顏色是GL.Color( new Color(1,1,1,0.5f) );設置的顏色
   如果是GL.TRIANGLES或者是GL.QUADS,則顏色是shader裏的顏色。

1.
GL.PushMatrix()
保存matrices至matrix stack上。
GL.PopMatrix()
從matrix stack上讀取matrices。

2.
GL.LoadPixelMatrix()
改變MVP矩陣,使得transform裏的xy 直接對應像素,(0,0)表示屏幕viewport的左下角,z的範圍是(-1,1),該函數改變camera的參數,所以需要GL.PushMatrix()保存和GL.PopMatrix()讀取。
GL.Vertex3()的取值範圍從左下角的(0,0,0) 至右上角的(Screen.width,Screen.height,0)

GL.LoadOrtho()
設置ortho perspective,即水平視角。After calling LoadOrtho, the viewing frustum goes from (0,0,-1) to (1,1,100). 主要用於在純2D裏繪製圖元。
GL.Vertex3()的取值範圍從左下角的(0,0,0) 至右上角的(1,1,0)

3.
OnPostRender()
只有物體上有激活的攝像機時,纔會調用的函數,當攝像機完成渲染場景,繪製了所有物體以後調用。
OnPostRender可以變成co-routine,加yield語句即可。

WaitForEndOfFrame()
等待至 所有繪製之後,end of frame, 就在展示frame到屏幕之前。可以做截圖。可以在任何物體上使用該函數。

[csharp] view plain copy
  1. 例1:屏幕畫線  
  2.    
  3. using UnityEngine;  
  4. using System.Collections;  
  5.   
  6. public class GLTest : MonoBehaviour {  
  7.   
  8.   public Material mat;  
  9.     void OnPostRender() {  
  10.         if (!mat) {  
  11.             Debug.LogError("Please Assign a material on the inspector");  
  12.             return;  
  13.         }  
  14.         GL.PushMatrix(); //保存當前Matirx  
  15.         mat.SetPass(0); //刷新當前材質  
  16.         GL.LoadPixelMatrix();//設置pixelMatrix  
  17.         GL.Color(Color.yellow);  
  18.         GL.Begin(GL.LINES);  
  19.         GL.Vertex3(0, 0, 0);  
  20.         GL.Vertex3(Screen.width, Screen.height, 0);  
  21.         GL.End();  
  22.         GL.PopMatrix();//讀取之前的Matrix  
  23.     }  
  24. }  

[csharp] view plain copy
  1. 例2:截圖  
  2.    
  3. using System.IO;  
  4. using UnityEngine;  
  5. using System.Collections;  
  6.   
  7. public class ScreenShot : MonoBehaviour {  
  8.     void Start() {  
  9.         StartCoroutine(UploadPNG() );  
  10.     }  
  11.     IEnumerator UploadPNG() {  
  12.         yield return new WaitForEndOfFrame();  
  13. print ("yuuuuu");  
  14.         int width = Screen.width;  
  15.         int height = Screen.height;  
  16.         Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);  
  17.         tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);  
  18.         tex.Apply();  
  19.         byte[] bytes = tex.EncodeToPNG();  
  20. File.WriteAllBytes(Application.dataPath+"/ss.png",bytes);  
  21. UnityEditor.AssetDatabase.Refresh();  
  22.     }  
  23. }  

[csharp] view plain copy
  1. 例3:展示Alpha  
  2.   
  3.    
  4. using UnityEngine;  
  5. using System.Collections;  
  6.   
  7. public class GLTest : MonoBehaviour {  
  8. public Shader shader;  
  9. public Texture2D t2d;  
  10.   private Material mat;  
  11. void Start()  
  12. {  
  13. mat = new Material(shader);  
  14. mat.mainTexture = t2d;  
  15. }  
  16.     void OnPostRender() {  
  17.         if (!mat) {  
  18.             Debug.LogError("Please Assign a material on the inspector");  
  19.             return;  
  20.         }  
  21.         GL.PushMatrix();  
  22.         mat.SetPass(0);  
  23.         GL.LoadOrtho();  
  24.         GL.Begin(GL.QUADS);  
  25.         GL.Vertex3(0, 0, 0.1F);  
  26.         GL.Vertex3(1f, 0, 0.1F);  
  27.         GL.Vertex3(1f, 1, 0.1F);  
  28.         GL.Vertex3(0, 1, 0.1F);  
  29.         GL.End();  
  30.         GL.PopMatrix();  
  31.     }  
  32. }  
  33. Shader "Custom/GLDrawLine" {  
  34. Properties {  
  35. _MainTex ("Base (RGB)", 2D) = "white" {}  
  36. }  
  37. SubShader {  
  38.     Pass {  
  39. Cull off  
  40. Blend DstAlpha zero  
  41. Color(1,1,1,1)  
  42.     }  
  43. }  
  44. }  
發佈了35 篇原創文章 · 獲贊 20 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章