[程式] 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