天天看點

【Unity3D日常開發】Unity3D Unity 幾種畫線方式

【前言】

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

例如在戰鬥中,可能需要知道所有機關的仇恨值,如果這些資訊全打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

  1. 一般在Update/Fixed Update/LateUpdate裡調用
  2. 隻在Scene視窗裡顯示
  3. 并且不能設定材質
void Update()
{
     Debug.DrawLine (worldPos1, worldPos2,Color.yellow);
}
      

(2)Gizmos.Draw

  1. 在OnDrawGizmos /OnDrawGizmosSelected裡調用
public void OnDrawGizmosSelected() 
{
    Gizmos.DrawLine(Vector3.zero, new Vector3(0,3f,0));
}
      

(3)Graphic.DrawMesh

  1. 實際螢幕和Scene視窗都能顯示
  2. 可以設定材質

    畫Mesh

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

(4)GL

  1. 一般在物體的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()裡執行。

或者挂在物體上

注意:

  1. GL的線等基本圖元并沒有uv. 所有是沒有貼圖紋理影射的,shader裡僅僅做的是單色計算或者對之前的影像加以處理。
  2. GL所使用的shader裡必須有Cull off指令,否則顯示會變成如下
  3. 如果是線,顔色是GL.Color( new Color(1,1,1,0.5f) );設定的顔色
  4. 如果是GL.TRIANGLES或者是GL.QUADS,則顔色是shader裡的顔色。

主要API解析

  1. GL.PushMatrix()

    儲存matrices至matrix stack上。

  2. GL.PopMatrix()

    從matrix stack上讀取matrices。

  3. GL.LoadPixelMatrix()

    改變MVP矩陣,使得transform裡的xy 直接對應像素,(0,0)表示螢幕viewport的左下角,z的範圍是(-1,1),該函數改變camera的參數,是以需要GL.PushMatrix()儲存和GL.PopMatrix()讀取。

  4. GL.Vertex3()

    取值範圍從左下角的(0,0,0) 至右上角的(Screen.width,Screen.height,0)

  5. GL.LoadOrtho()

    設定ortho perspective,即水準視角。After calling LoadOrtho, the viewing frustum goes from (0,0,-1) to (1,1,100). 主要用于在純2D裡繪制圖元。

  6. 的取值範圍從左下角的(0,0,0) 至右上角的(1,1,0)
  7. 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)  
   	 }  
  }  
}  
      

繼續閱讀