在UE5添加自定义的设置面板

UE5.0 中的设置面板有两种,一个是Editor Preferences,另一个是Project Settings


下面将用C++在这两个面板内添加自定义的设定

方法1:继承UObject,手动注册

新建一个C++工程,名为MyDemo。

编写一个设置面板类UMyCustomSetting,成员变量作为设置面板的设置内容。

MyCustomSetting.h

#pragma once

#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "MyCustomSetting.generated.h"


UCLASS()
class MYDEMO_API UMyCustomSetting : public UObject
{
	GENERATED_BODY()
	
public:
	UPROPERTY(EditAnywhere, Category = Setting1)
	bool UseCustomSetting;

	UPROPERTY(EditAnywhere, Category = Setting2, meta=(UIMin=1,EditConditionHides=true,EditCondition="UseCustomSetting==true"))
	float Health = 100;

	UPROPERTY(EditAnywhere, Category = Setting2, meta=(UIMin=30,UIMax=300,EditConditionHides=true,EditCondition="UseCustomSetting==true"))
	float Ammo = 240;
};

然后在模块启动时注册UMyCustomSetting类,所以我们先新建一个FMyDemoGameModule模块,在模块启动时注册Setting类,模块关闭时反注册。

MyDemo.h

#pragma once

#include "CoreMinimal.h"

class FMyDemoGameModule : public IModuleInterface
{
public:
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
	virtual bool IsGameModule() const override;
};

MyDemo.cpp

#include "MyDemo.h"

#include "ISettingsModule.h"
#include "MyCustomSetting.h"
#include "Modules/ModuleManager.h"

void FMyDemoGameModule::StartupModule()
{
	ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
	if (SettingsModule != nullptr)
	{
		SettingsModule->RegisterSettings("Editor", "MyDemo", "My Custom Setting",
			FText::FromString(TEXT("我的自定义设置")),
			FText::FromString(TEXT("这是自定义设置的描述")),
			GetMutableDefault<UMyCustomSetting>());
	}
}

void FMyDemoGameModule::ShutdownModule()
{
	ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
	if (SettingsModule != nullptr)
	{
		SettingsModule->UnregisterSettings("Editor", "MyDemo", "My Custom Setting");
	}
}

bool FMyDemoGameModule::IsGameModule() const
{
	return true;
}

IMPLEMENT_PRIMARY_GAME_MODULE(FMyDemoGameModule, MyDemo, "MyDemo");

注册设置面板调用的是ISettingModule的RegisterSettings函数

其中ContainerName可以指定“Project”或“Editor”,分别对应Project SettingsEditor Preferences

其他参数对应的内容如下图:

方法2:继承UDeveloperSettings类,引擎自动注册

MyCustomSetting2.h

#pragma once

#include "CoreMinimal.h"
#include "Engine/DeveloperSettings.h"
#include "MyCustomSetting2.generated.h"


UCLASS()
class MYDEMO_API UMyCustomSetting2 : public UDeveloperSettings
{
	GENERATED_BODY()

public:
	
	// 等效方法1的ContainerName参数
	virtual FName GetContainerName() const override
	{
		return "Project";
	}
	// 等效方法1的CategoryName参数
	virtual FName GetCategoryName() const override
	{
		return "MyDemo";
	}
	// 等效方法1的SectionName参数
	virtual FName GetSectionName() const override
	{
		return "My Custom Setting";
	}
	// 等效方法1的DisplayName参数
	virtual FText GetSectionText() const override
	{
		return FText::FromString(TEXT("我的自定义设置"));
	}
	// 等效方法1的Description参数
	virtual FText GetSectionDescription() const override
	{
		return FText::FromString(TEXT("这是自定义设置的描述"));
	}
	
	UPROPERTY(EditAnywhere, Category = Setting1)
	bool UseCustomSetting;

	UPROPERTY(EditAnywhere, Category = Setting2, meta=(UIMin=1,EditConditionHides=true,EditCondition="UseCustomSetting==true"))
	float Health = 100;

	UPROPERTY(EditAnywhere, Category = Setting2, meta=(UIMin=30,UIMax=300,EditConditionHides=true,EditCondition="UseCustomSetting==true"))
	float Ammo = 240;
};

第二种方法不用考虑何时注册,而且提供了属性更改时触发的多播代理FOnSettingsChanged

 最终效果如上图


保存设置面板的内容

上一小节中,我们实现了自定义的面板,但是有个问题,修改后的值并没有保存,每次打开编辑器都会恢复默认的值。

以UMyCustomSetting类为例

UCLASS(Config=MyDemo, DefaultConfig)
class MYDEMO_API UMyCustomSetting : public UObject
{
	...
};

1. 在UCLASS指定类说明符:Config=MyDemo, DefaultConfig

这些说明符的含义可以在官方文档内可以查到

Config=ConfigName :指示此类可在*.ini文件中存储数据,`ConfigName`为文件名称。常见的`ConfigName`值是"Engine"、"Editor"、"Input"和"Game"。

DefaultConfig:仅将类配置保存到Default[ConfigName].ini,不保存到本地 (Saved文件夹)。

此外,还有备选说明符:

PerObjectConfig:为每个实例保存配置文件。

ConfigDoNotCheckDefaults:序列化类的时候不会检查默认配置内的值

2. 为UPROPERTY添加说明符

UPROPERTY(Config, EditAnywhere, Category = Setting1)
bool UseCustomSetting;

Config:有此说明符的Property会被保存到配置文件内对应的Section中。

GlobalConfig:跟Config差不多,但是子类的该Property会从基类中读取值。

项目文件夹Config中可以找到保存的ini文件


访问设置类内的参数

使用CDO来访问设置参数

GetDefault<T>() 可以获取const T*

GetMutableDefault<T>()可以获取T*,可以用来修改Setting类内的数值

// 访问使用GetDefault
const UMyCustomSetting* MyCustomSetting = GetDefault<UMyCustomSetting>();
if (MyCustomSetting)
{
	FString TrueOrFalse = MyCustomSetting->UseCustomSetting ? L"True" : L"False";
	UE_LOG(LogTemp, Display, TEXT("UseCustomSetting = %s"), *TrueOrFalse);
		
	if (MyCustomSetting->UseCustomSetting)
	{
		UE_LOG(LogTemp, Display, TEXT("Health=%d, Ammo=%d"), MyCustomSetting->Health,MyCustomSetting->Ammo);
	}
}

// 修改使用GetMutableDefault
UMyCustomSetting2* MyCustomSetting2 = GetMutableDefault<UMyCustomSetting2>();
if (MyCustomSetting2)
{
	MyCustomSetting2->UseCustomSetting = true;
	MyCustomSetting2->Health = 150;
	MyCustomSetting2->Ammo = 300;	
}

猜你喜欢

转载自blog.csdn.net/qq_25521145/article/details/127456680
今日推荐