1. 程式人生 > >[Unity]各種Debug方法筆記

[Unity]各種Debug方法筆記

無論是萌新還是Dalao,遇到Bug總是難免的(拒絕反駁)
所以一些好的Debug方法就顯得尤為重要
這篇文章既寫給自己,也給看到文章的大家一個參考
內容主(quan)要(bu)是指令碼的Debug方法

ps:如有出錯漏記得以我能看到的方式指出www

Inspector

好像不只是一個Debug方法

首先(我)用的頻率最高的東西,毫無疑問是Unity
的Inspector
Inspector示意

可以看到有很多元件,因為這個是我拿來測試各種功能的GameObject
在上面可以檢視到很多元件的公開欄位
比如我在Tester裡面加上:

public float testNumber = 0.1
f;

儲存 切回Unity就可以看到:
public的float
注意到了嗎?首字母大寫之外,第二個單詞Number因為我首字母N大寫了,所以Unity自動劃成兩個單詞了
初始值也顯示了出來。
除了能夠在執行時顯示、修改之外,編譯出來的場景中也會使用你在Inspector裡寫的值

然而有人可能會說,這是我的一個私有變數,又想通過Inspector的方式修改、儲存怎麼辦?
一般來講可以:

[SerializeField] private float testNumber = 0.1f;

在你想要顯示的變數前面加上[SerializeField]就可以強制Unity在Inspector顯示它。
然而某些情況下甚至連程式碼都不想改,怎麼辦呢?
這裡就要用到Inspector的黑科技了
Inspector->Debug


可以看到Inspector裡面立馬多出了一大堆東西

比如我的Tester裡面就有:
Tester
Instance ID:不知道是什麼
Local Identfier In File:好像跟.meta有關?
Script:就是我的指令碼了
Test Number:這個是我在Tester裡面寫的一個私有變數,也被顯示出來了。但是灰色表明處於無法編輯的狀態

再來看看左上角的這個橙色的球球,不知道你們有沒有點開看過呢?
Select Icon

一開始我根本不知道這個花裡花俏的是什麼鬼玩意兒,直到我隨便點了一個,看到了:
橙色的圖示
Amazing!這樣我就能夠在場景中準確找到連模型都沒有的物體了!豈不美哉?
各位看官沒事隨便點點,總有一個適合你的圖示///

這是我目前能找到的全部Inspector的神奇用法了

UnityEngine.Debug

這裡的「Debug」是名詞 大概吧

接下來看看程式碼部分的方法
先科普一下

if (Input.GetKeyDown(KeyCode.T))
{
    //這一段能檢測是否按下了T鍵
}

然後捧出神器:
Debug類
這個怎麼用呢?還是用Update來演示吧

private void Update()
{
    if (Input.GetKeyDown(KeyCode.T))
    {
        //這一段能檢測是否按下了T鍵
        Debug.Log("你按下了T鍵.");
    }
}

執行一下可以看到:
Console
1、按下T鍵之後,螢幕左下角顯示了一條我寫的文字
2、點選這個文字發現有一個彈窗(Console)
3、我按了30次T,右邊也計數30次了
然而Debug的神奇之處還不止這個
再來看看這一堆程式碼:

private void Update()
{
    //把剛剛的程式碼剪下到ABC裡面了
    ABC();
}

private void ABC()
{
    if (Input.GetKeyDown(KeyCode.T))
    {
        //這一段能檢測是否按下了T鍵
        Debug.Log("你按下了T鍵.");
    }
}

再試一次可以看到:
詳細的Log呼叫棧
仔細看下面的資訊:

你按下了T鍵.======這一行不用解釋
UnityEngine.Debug:Log(Object)======表示呼叫了Log
Tester:ABC() (at Assets/Scipts/Tester.cs:22)======呼叫了ABC(),在Tester的第22行
Tester:Update() (at Assets/Scipts/Tester.cs:14)======Update()中呼叫了ABC()(第14行)
也就是說,Debug甚至能告訴你從哪個函式呼叫到哪個函式,在哪一行使用了Log

現在再來試試別的:

private void Update()
{
    SaySomeThing();
}

private void SaySomeThing()
{
    if (Input.GetKeyDown(KeyCode.T))
    {
        //這一段能檢測是否按下了T鍵
        Debug.Log("你按下了T鍵.");
        Debug.LogWarning("你竟然按下了T鍵!");
        Debug.LogError("你本不該按下T的。。。");
    }
}

這三個的區別很明顯,就不多說了
三種Log的方式

順便再提提上面幾個按鈕的用處
Console的按鈕

ps:善用Debug.Log()系列能帶來很多意想不到的結果呢www

UnityEngine.Debug:視覺化除錯

除了能輸出Log資訊之外,Debug這個類還允許你:
在場景上畫一條線

private void Update()
{
    //對 我就是喜歡在Update測試
    //注意這裡是GetKey(),意思是鍵盤保持按下的狀態就會返回true
    if (Input.GetKey(KeyCode.T))
    {
        //a,b是兩個向量
        Debug.DrawLine(a, b, Color.blue, 1f, false);
    }
}

DrawLine:顧名思義,畫線

第一、二個引數(a,b)分別是起點、終點
第三個引數(Color.blue)是顏色
第四個引數(1f)是畫出來的線停留的時間
第五個引數(false)為true代表會被物體遮擋,false代表不會(預設好像是false)
可以在Scene看到這條藍色的線
DrawLine示例
類似的還有:

Debug.DrawRay(a, b, Color.red, 1f);

要注意的是,這裡的第二個引數不是座標,而是帶長度的方向
或者說,以起始點為原點的終點座標
所以其實是DrawLine的另一種形式,並不是數學意義上的射線
DrawRay示例

這個圖裡的紅色線就是DrawRay畫出來的線,b=(10,0,0)

雜項

自己鼓搗出來的不知道什麼鬼玩意兒

由於使用Unity的時間並不長,C#也是接觸Unity才開始用的,至今也就研究出了一個方法
首先不知道訪問器是啥的同學先去看一下這個

在某些情況下
你可能需要監測一個變數

雖然我其實也不是很分得清 屬性 欄位 變數 這幾個概念(:з」∠)

但是……
某個類裡有一個float number
可是有十幾行都呼叫了它啊!我總不能每一行都加一個Debug.Log()吧!總不能修好之後又十幾行地去掉吧!
於是我這樣寫:

private float _number;//加一個變數
private float number
{
    get
    {
        Debug.Log("number被讀了"); //讀取打個log
        return _number;
    }set
    {
        Debug.Log("number被寫了");//寫入打個log
        _number = value;
    }
}

是不是很機智!這樣改的話,我不用改後面的程式碼,因為訪問器的呼叫和變數的呼叫是一模一樣的,卻能實現每一次讀/寫都能Log一次!而且Debug結束之後可以把Debug用的程式碼全部刪掉,留下

private float number;

就可以保證程式碼正常運行了
妙哇 (p≧ V ≦q)




今天就寫到這裡了,希望大家都能有所收穫哈