【前言】
圖形化調試可以加速開發。
例如在戰鬥中,可能需要知道所有機關的仇恨值,如果這些資訊全打log的話,很難有直覺感受,
而如果在Scene視窗裡,機關頭頂有一個球,越紅表示仇恨越高,越暗表示仇恨越低,那麼調試起來比打log直覺多了。
【一 、圖形化調試】
Unity中圖形化調試主要4種
- Debug.Draw
- Gizmos.Draw
- Graphic.DrawMesh
- GL
有兩種情況
1.隻需在Scene視窗顯示的調試圖像
- 一直顯示的 OnDrawGizmos + Gizmos.Draw
- 選中顯示的 OnDrawGizmosSelected + Gizmos.Draw
- 腳本控制的 Update + Debug.Draw
2.需要在實際裝置螢幕顯示的調試圖像
- Update+Graphic.DrawMesh
- OnRenderObject+GL
Graphic.DrawMesh和Debug.Draw 調用一緻,都是在Update系裡
Graphic.DrawMesh和GL 顯示類似,都在各個視窗顯示,并且可以設定材質。
四種方式比較
(1)Debug.Draw
- 一般在Update/Fixed Update/LateUpdate裡調用
- 隻在Scene視窗裡顯示
- 并且不能設定材質
void Update()
{
Debug.DrawLine (worldPos1, worldPos2,Color.yellow);
}
(2)Gizmos.Draw
- 在OnDrawGizmos /OnDrawGizmosSelected裡調用
public void OnDrawGizmosSelected()
{
Gizmos.DrawLine(Vector3.zero, new Vector3(0,3f,0));
}
(3)Graphic.DrawMesh
- 實際螢幕和Scene視窗都能顯示
-
可以設定材質
畫Mesh
void Update()
{
Graphics.DrawMesh(mesh, worldPos, worldRotation, material, 0);
}
(4)GL
- 一般在物體的OnRenderObject 或者相機的OnPostRender裡調用
一個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()裡執行。
或者挂在物體上
注意:
- GL的線等基本圖元并沒有uv. 所有是沒有貼圖紋理影射的,shader裡僅僅做的是單色計算或者對之前的影像加以處理。
- GL所使用的shader裡必須有Cull off指令,否則顯示會變成如下
- 如果是線,顔色是GL.Color( new Color(1,1,1,0.5f) );設定的顔色
- 如果是GL.TRIANGLES或者是GL.QUADS,則顔色是shader裡的顔色。
主要API解析
-
GL.PushMatrix()
儲存matrices至matrix stack上。
-
GL.PopMatrix()
從matrix stack上讀取matrices。
-
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裡繪制圖元。
- 的取值範圍從左下角的(0,0,0) 至右上角的(1,1,0)
-
OnPostRender()
隻有物體上有激活的錄影機時,才會調用的函數,當錄影機完成渲染場景,繪制了所有物體以後調用。
例1:螢幕畫線
using UnityEngine;
using System.Collections;
public class GLTest : MonoBehaviour {
public Material mat;
void OnPostRender() {
if (!mat) {
Debug.LogError("Please Assign a material on the inspector");
return;
}
GL.PushMatrix(); //儲存目前Matirx
mat.SetPass(0); //重新整理目前材質
GL.LoadPixelMatrix();//設定pixelMatrix
GL.Color(Color.yellow);
GL.Begin(GL.LINES);
GL.Vertex3(0, 0, 0);
GL.Vertex3(Screen.width, Screen.height, 0);
GL.End();
GL.PopMatrix();//讀取之前的Matrix
}
}
例2:截圖
using System.IO;
using UnityEngine;
using System.Collections;
public class ScreenShot : MonoBehaviour {
void Start() {
StartCoroutine(UploadPNG() );
}
IEnumerator UploadPNG() {
yield return new WaitForEndOfFrame();
print ("yuuuuu");
int width = Screen.width;
int height = Screen.height;
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
File.WriteAllBytes(Application.dataPath+"/ss.png",bytes);
UnityEditor.AssetDatabase.Refresh();
}
}
例3:展示Alpha
using UnityEngine;
using System.Collections;
public class GLTest : MonoBehaviour {
public Shader shader;
public Texture2D t2d;
private Material mat;
void Start()
{
mat = new Material(shader);
mat.mainTexture = t2d;
}
void OnPostRender() {
if (!mat) {
Debug.LogError("Please Assign a material on the inspector");
return;
}
GL.PushMatrix();
mat.SetPass(0);
GL.LoadOrtho();
GL.Begin(GL.QUADS);
GL.Vertex3(0, 0, 0.1F);
GL.Vertex3(1f, 0, 0.1F);
GL.Vertex3(1f, 1, 0.1F);
GL.Vertex3(0, 1, 0.1F);
GL.End();
GL.PopMatrix();
}
}
Shader "Custom/GLDrawLine" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
}
SubShader {
Pass {
Cull off
Blend DstAlpha zero
Color(1,1,1,1)
}
}
}