“脏”(Dirty)的意思
当用户对一个资源包(关卡,或材质等美术资源)做出了修改,变得与磁盘上存储的内容有差异时,UE会对其“标脏”(Mark Dirty),显示为 *
符号:
为何要查“资源包因何变脏”?
对于用户来说,“脏”意味着有修改,用户需要决定是否需要保存。但如果资源包被未知的原因标脏,用户将无法决定是否要保存,毕竟他们连修改了啥都不知道!
对于程序来说,可能会有些逻辑依赖于“脏”,比如一个命令仅会保存被标脏的资源。如果资源包被未知的原因标脏,那么此命令将会保存多余的资源,使其行为看起来不符合预期。
查“资源包因何变脏”的方式
我目前的方式是在此加断点:
\Engine\Source\Runtime\CoreUObject\Private\UObject\Package.cpp 中的Package::SetDirtyFlag
函数。
首先确定传入的bInIsDirty
参数是true
,因为这样才是“标脏”。而false
是“清除脏标记”。
this
指针可以让你确定此处断点确实是你想要调查的资源包。
“调用堆栈” 窗口指出了资源包因何变脏。
这个测试中,我实际上是通过界面上改变了当前关卡的一个属性。它对应了上面的堆栈
建议
如果你已经将“未知的标脏行为”确定到了一个较小的范围内,并且可以轻易复现,那么直接加断点即可。
但若嫌疑范围较大,那么加断点后,很可能会触发其他你并不想调查的资源包的标脏行为,需要跳转多次才轮到你调查的那个资源包。此时,最好缩小嫌疑范围。
我一般采用的方式是在此处加log,比如在Package::SetDirtyFlag
函数的开头插入临时代码:
UE_LOG(LogTemp, Warning, TEXT("TestYaksue: %s SetDirty: %s"), *GetName(), bInIsDirty ? TEXT("true") : TEXT("false"));
接着,就可以在log中寻找自己感兴趣的资源包的名字,并结合出现位置上下的log,来缩小标脏行为的范围了: