[程式] UE4 除錯技巧分享 (一)

作者: yekdniw (yekdniw)   2020-08-19 11:28:26
網頁版
https://yekdniwue.blogspot.com/2020/08/ue4CodeTrace1.html
俗話說的好
給他魚吃不如教他釣魚
今天要分享幾個我平常在用的技巧
心理建設
如果你是有程式背景,但是正在用blueprint(BP)開發。
那我會建議你要先幫自己做好心裡建設。
你在用的是開發原始碼的引擎,
遇到問題時應該儘量往引擎內部追,
不要馬上就找繞過(workaround)的方法或求救。
那樣作你很快就會想放棄,因為無法進步,遇到問題無法自救。
硬體設備
雖說是技巧心得,理論上要跟硬體無關,但是這個真的要講一下。
想追code一定要準備好2個螢幕以上,
至少一個螢幕是UE4 Editor,另一個是Visual Studio。
單螢幕的話光是切換視窗就亂掉了。
技巧分享
這裡面的技巧應該比較零散,所以可以跳著看。
不寫Code就直接顯示變數值在螢幕上
如果問我只能寫一條的話,我一定選這一條。
這個是我第一常用的技巧了,大部分我們想到要得知某一個值,
就是跑去Actor或是Component的Tick裡面下PrintString,
這樣資訊就會顯示在畫面上。如下圖。
[圖]
可是有的時候bug是機率出現的,好不容易bug發生了,想看某個值是否異常,但是當下卻
沒有埋PrintString,難道只能放棄了嗎?
其實沒有,引擎提供了強大的console command "DisplayAll",
讓我們可以直接拿到變數值並顯示於螢幕。如圖。
[圖]
DisplayAll的使用方法是:
DisplayAll [ClassName] [PropertyName]
大小寫無分別,所以可以不管大小寫。
ClassName的部份,可分為C++與BP class兩種。
如果你要追查的class是C++ class,那麼直接輸入C++的名稱就好,
但是要去除第一個字。例如
AActor應該輸入Actor
想知道movement移動速度的最大值可下
displayall charactermovementcomponent maxwalkspeed
如果你要追查的class是BP,那麼你要輸入[BP的名稱_C],
舉例來說
有一個BP名稱為BP_CodeTraceActor 裡面有一個變數是value
那麼要輸入的是
DisplayAll BP_CodeTraceActor_c value
PropertyName的部份,只要這個變數有被定義為UPROPERTY,就可以拿到值。
BP所有的變數應該都有UPROPERTY,所以沒問題。
資料顯示出來後,我通常會搭配桌面錄影軟體搭配測試,
一有問題就可以把影片檔抓出來單格播放,
抓出異常的時間點,然後再回去想想問題可能出在哪裡。
故障排除
如果輸入之後畫面沒任何東西,建議先輸入一定會出現的指令確認
例如
diaplayall playercontroller spawnLocation
如果這樣看的到,那可能是你的class name打錯,系統找不到。
如果這樣還看不到,檢查一下自己的環境是不是Debug / Development,
還是有什麼東西關掉。
如果輸入之後畫面有字,但是沒有值(有綠色的字沒有紅色的字),
那可能是PropertyName打錯,建議檢查一下。
我宣布放棄DisplayAll列出來的資訊
只要執行Console Command
DisplayClear
就可以了
DisplayAll使用條件限制與缺點
限制
DisplayAll只會在Debug以及Development顯示,
所以如果在Test跟Shipping是看不到的。
Dedicated Server因為沒有螢幕,所以也看不到。
但是如果Dedicated Server + SingleProcess模式的話,
畫面上會同時列出Server跟Client的值,很好用。
相反的Editor/ Packaged Development Game都看的到,
建議可以多加利用。
缺點
使用DisplayAll最大的缺點就是只能根據class列出,
沒有辦法針對某個class的某個實體(Instance)輸出。
所以class沒有選擇好的話就會列出過多資訊,
無法好好地做判斷。
另一個就是如果值在一個frame裡面會變動多次,
想要從DisplayAll抓出問題也沒辦法,
畢竟這個功能一個frame只會更新一次。
避免程式碼被Optimize造成中斷點失效
一般我們都是使用Development Editor在開發,
但是因為編譯器會做Code Optimization的關係,
有的時候中斷點會無效或異常。
經驗上有以下幾種現象會因為Code Optimize產生:
1. 斷點失效,雖然Visual Studio顯示該行有下斷點,
但是有執行卻不停。
2. 斷點下不到準確的行數,例如下在53行卻顯示斷點在55行。
3. 執行順序怪異,跳下後又跳上,或是直接跳過整段,
或是走到一半就離開函式。
4. 看不到變數值
下圖就是想看變數MutableThis內容看不到的範例。
[圖]
這個時候,如果真的非得知道這個值,
常見的解法就是加Log強制印出,
或是編譯DebugGame Editor,
或是Debug Editor等等。
但是我個人最常用的方式是直接使用Macro Define,
把想看的函式夾起來,
不用改DebugGame Editor或是Debug Editor。
範例如下
PRAGMA_DISABLE_OPTIMIZATION
//Your codes here
PRAGMA_ENABLE_OPTIMIZATION
下圖就是使用PRAGMA後可以成功拿到值的範例
[圖]
這個方法有幾個好處:
1. 編譯速度快,因為相當於改cpp code而已,
不像切換成DebugGame Editor,
如果先前沒有build過要等很久。
2. 省硬碟空間,切換成DebugGame Editor,
就會多出Debug版本的dll,吃掉硬碟空間。
3. 效能沒有受到犧牲,如果用DebugEditor的話,
整個編輯器會變得很慢,這個方法不會。
這個方法的缺點:
目前我使用到最大的缺點就是,這段PRAGMA要記得除錯完就刪掉,
不然這段程式碼都不會做Optimization,執行效能是會受到影響的。
然後有很少數的情況夾了還是有部分看不到,
這時候我就會直接夾整個cpp檔,通常就沒問題了。
其實還有一個缺點,就是這兩行我永遠背不起來,
每次都要去筆記本裡面複製貼上。
對我來說,這個方法沒什麼負擔跟缺點,很推薦大家學起來,推推!
下回預告
預計下個禮拜會分享第二集,是有關如何在UE4中使用中斷點的部份
作者: metallican (鋼鐵人)   2020-08-19 17:27:00
每次都超期待大大的文的 能學到許多東西 感謝大大
作者: coolrobin (泳圈)   2020-08-19 21:16:00
居然有display all這個指令... 學習了 m(_"_)m
作者: PathosCross (木偶君)   2020-08-19 23:23:00
實用技巧推
作者: strangechu (電冰箱)   2020-08-20 10:18:00
我就是那個只會改Debug的人 學習了
作者: ConSeR (草履重根)   2020-08-21 09:31:00
感謝分享
作者: heavendemon   2020-10-05 13:51:00
正在學 感恩推

Links booklink

Contact Us: admin [ a t ] ucptt.com