3.5 KiB
Raw Blame History

ConfigDoNotCheckDefaults

  • 功能描述: 指定在保存配置值的时候忽略上一级的配置值的一致性检查。
  • 引擎模块: Config
  • 元数据类型: bool
  • 作用机制: 在ClassFlags中增加CLASS_ConfigDoNotCheckDefaults
  • 关联项: Config
  • 常用程度:★

指定在保存配置值的时候忽略上一级的配置值的一致性检查。

  • 在保存配置的时候决定是否要先根据Base或Default的配置来检查属性是否一致如果一致就不用序列化写入下来。但加上这个标志后即使同上一个层级的配置值相同也无论如何都要保存下来。

UCLASS(config=XXX,configdonotcheckdefaults)表示这个类对应的配置文件不会检查XXX层级上层的DefaultXXX配置文件是否有该信息后面会解释层级就直接存储到Saved目录下。

示例代码:

UCLASS(Config = Game)
class INSIDER_API UMyClass_Config :public UObject
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
		int32 MyProperty = 123;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Config)
		int32 MyPropertyWithConfig = 123;
};

UCLASS(Config = Game,configdonotcheckdefaults)
class INSIDER_API UMyClass_ConfigDoNotCheckDefaults :public UMyClass_Config
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Config)
		int32 MyPropertyWithConfigSub = 123;
};

UCLASS(Config = Game)
class INSIDER_API UMyClass_ConfigDefaultChild :public UMyClass_Config
{
	GENERATED_BODY()
public:
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Config)
		int32 MyPropertyWithConfigSub = 123;
};

示例效果:

void UMyClass_Config_Test::TestConfigCheckDefaultSave()
{
	auto* testObject = NewObject<UMyClass_ConfigDoNotCheckDefaults>(GetTransientPackage(), TEXT("testObjectCheckDefault"));
	auto* testObject2 = NewObject<UMyClass_ConfigDefaultChild>(GetTransientPackage(), TEXT("testObjectDefaultChild"));

	testObject->SaveConfig();
	testObject2->SaveConfig();
}

生成:
[/Script/Insider.MyClass_Config]
MyPropertyWithConfig=777

[/Script/Insider.MyClass_ConfigDoNotCheckDefaults]
MyPropertyWithConfigSub=123
MyPropertyWithConfig=777

[/Script/Insider.MyClass_ConfigDefaultChild]
MyPropertyWithConfigSub=123

由此可见MyClass_ConfigDoNotCheckDefaults中的MyPropertyWithConfig的值默认跟UMyClass_Config中的777值一致但是依然会写入进来。在MyClass_ConfigDefaultChild类中MyPropertyWithConfig的值因为没有改变就会被略过。

在源码里搜configdonotcheckdefaults的时候发现常常和defaultconfig配合使用。什么时候应该使用configdonotcheckdefaults感觉是为了保持自己的完整性无论如何都要全部写入进去。在defaultConfig的时候就可以不管Base里的值都写入一份到Default配置里这样在编辑上更加的完整。

原理:

const bool bShouldCheckIfIdenticalBeforeAdding = !GetClass()->HasAnyClassFlags(CLASS_ConfigDoNotCheckDefaults) && !bPerObject && bIsPropertyInherited;
//简单的示例判断
if (!bPropDeprecated && (!bShouldCheckIfIdenticalBeforeAdding || !Property->Identical_InContainer(this, SuperClassDefaultObject, Index)))
{
	FString	Value;
	Property->ExportText_InContainer( Index, Value, this, this, this, PortFlags );
	Config->SetString( *Section, *Key, *Value, PropFileName );
}
else
{
	// If we are not writing it to config above, we should make sure that this property isn't stagnant in the cache.
	Config->RemoveKey( *Section, *Key, PropFileName );
}