通过AutoExpand调试Unreal内置数据类型 --Zephyroal
Unreal3引擎中,大量使用了自定义的模版或数据类型,比如TArray、FName、FString等等,想起了以前痛苦的utf-8编码调试,对于这类数据类型,难以在VS中直接查看他们的值。
同事偶然提到,网上一搜,万幸,有前人走过此路,通过扩展autoexp.dat可以实现对Unreal3数据类型的直观的可视化调试,方法如下:
1,打开调试时对变量进行Auto Expand功能
首先,确保功能打开:
VS的Option->Debug->General
2,[AutoExpand]字段
打开VS安装目录下的Common7/Packages/Debugger/autoexp.dat文件 ,找到[AutoExpand],
(注,其实无所不能的Epic开发组早已经准备好了相关的文件,放在UE开发文件中, External中VisualStudioDebugging的目录下,由于开发环境的问题,不能放出,这里直接转用网上同仁发的脚本,如有不好用的地方,可参照原理,自行修改之,另外还可以举一反三,扩展到其它的情况下使用)
在[AutoExpand]的下面添加一行:
FNameEntry=<Name,su>
翻到文件最后,添加以下代码到文件的最后:
; Unreal格式的数组
TArray<*>{
children
(
#array
(
expr : (($T1*)($c.Data))[$i],
size : $c.ArrayNum
)
)
preview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : (($T1*)($c.Data))[$i],
size : $c.ArrayNum
),
")"
)
)
}
; Unreal格式的FName
FName{
preview([((FNameEntry**)FName.Names.Data)[$c.Index]])
stringview([((FNameEntry**)FName.Names.Data)[$c.Index]])
}
; Unreal格式的字符串
FString{
preview([$c.Data,su])
stringview([$c.Data,su])
}
3,[Visualizer]字段
在[Visualizer]下添加如下脚本:
; Unreal格式的数组
TArray<FString>{
children
(
#array
(
expr : ((FString*)($c.Data))[$i],
size : $c.ArrayNum
)
)
preview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FString*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
stringview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FString*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
}
TArrayNoInit<FString>{
children
(
#array
(
expr : ((FString*)($c.Data))[$i],
size : $c.ArrayNum
)
)
preview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FString*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
stringview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FString*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
}
; Unreal格式的数组
TArray<FStringNoInit>{
children
(
#array
(
expr : ((FStringNoInit*)($c.Data))[$i],
size : $c.ArrayNum
)
)
preview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FStringNoInit*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
stringview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FStringNoInit*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
}
TArrayNoInit<FStringNoInit>{
children
(
#array
(
expr : ((FStringNoInit*)($c.Data))[$i],
size : $c.ArrayNum
)
)
preview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FStringNoInit*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
stringview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : [((FStringNoInit*)($e.Data))[$i].Data,su],
size : $c.ArrayNum
),
")"
)
)
}
; Unreal格式的数组
TArray<*>{
children
(
#array
(
expr : (($T1*)($c.Data))[$i],
size : $c.ArrayNum
)
)
preview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : (($T1*)($c.Data))[$i],
size : $c.ArrayNum
),
")"
)
)
}
; Unreal格式的数组
TArrayNoInit<*>{
children
(
#array
(
expr : (($T1*)($c.Data))[$i],
size : $c.ArrayNum
)
)
preview
(
#(
"[",
$c.ArrayNum ,
"](",
#array
(
expr : (($T1*)($c.Data))[$i],
size : $c.ArrayNum
),
")"
)
)
}
; Unreal的FName
FName{
preview([((FNameEntry**)FName.Names.Data)[$c.Index]->Name,su])
stringview([((FNameEntry**)FName.Names.Data)[$c.Index]->Name])
}
; Unreal的FString
FString{
preview([$c.Data,su])
stringview([$c.Data,su])
}
; Unreal的FString
FStringNoInit{
preview([$c.Data,su])
stringview([$c.Data,su])
}
; Unreal的UObject
UObject{
preview([((FNameEntry**)FName.Names.Data)[$c.Index]->Name,su])
stringview([((FNameEntry**)FName.Names.Data)[$c.Index]->Name])
}
然后,开启Debug,Just Enjoy it!
4,相关知识
1) $e,$c是预先定义,表示是传给变量可视化调试器的值。用$e和$c都可以,没有区别。但是$c一般都用在container上。
2) $i是用在#array语句中的一个局部变量,使用了#array后会使用size表达式自动迭代$i
3) 分支语句#if #else:语句必须使用括号包起来,不能省略
4) 井号(#)语句:个人理解是一个串接语句,计算每一个在#('zz',$e.d,3)的变量,然后转为字符串,并串接起来。
5) #array:显示container的内容。需要提供expr和size表达式。expr就是每一个元素的内容,size就是总共显示多少个元素
6) 通配符(*)的使用:通配符经常用于名字空间通配和模板匹配,匹配上之后,会产生$T1,$T2...之类的类型或者名字空间。类型可以用来做类型转换。比如*::QList<*>匹配上QCore::QList<int>后$T1就是QCore,$T2就是int类型
7) 类型转换:通配到类型后可以使用C格式的强制转换。
8) 注释:只看到单行注释方式,使用分号(;)
9) 还有一种#tree的结构,用来显示层次化的数据结构
转自:
VS高级使用方法1:autoexp.dat使用Visual studio在debug时显示变量内容
在Visual Studio调试器中显示Unreal的数据类型的值
Thx!