Add a custom settings panel in UE5

There are two settings panels in UE5.0, one is Editor Preferences and the other is Project Settings .


The following will use C++ to add custom settings in these two panels

Method 1: Inherit UObject and register manually

Create a new C++ project named MyDemo.

Write a setting panel class UMyCustomSetting, the member variables are used as the setting content of the setting panel.

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;
};

Then register the UMyCustomSetting class when the module starts, so we first create a new FMyDemoGameModule module, register the Setting class when the module starts, and unregister it when the module is closed.

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");

The registration setting panel calls the RegisterSettings function of ISettingModule

Among them , ContainerName can specify "Project" or "Editor", corresponding to Project Settings and Editor Preferences respectively .

The corresponding content of other parameters is as follows:

Method 2: Inherit the UDeveloperSettings class, and the engine will automatically register

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;
};

The second method does not need to consider when to register, and provides a multicast agent FOnSettingsChanged triggered when the property changes

 The final effect is as shown above


Save the contents of the settings panel

In the previous section, we implemented a custom panel, but there is a problem that the modified value is not saved, and the default value will be restored every time the editor is opened.

Take the UMyCustomSetting class as an example

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

1. Specify the class specifier in UCLASS : Config=MyDemo, DefaultConfig

The meaning of these specifiers can be found in the official documentation

Config=ConfigName  : Indicates that this class can store data in *.ini files, `ConfigName` is the file name. Common `ConfigName` values ​​are "Engine", "Editor", "Input", and "Game".

DefaultConfig : Only save the class configuration to Default[ConfigName].ini , not to the local (Saved folder).

Additionally, there are alternative specifiers:

PerObjectConfig : Save configuration files for each instance.

ConfigDoNotCheckDefaults : When serializing classes, the values ​​​​in the default configuration will not be checked

2. Add specifier for UPROPERTY

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

Config : The Property with this specifier will be saved to the corresponding Section in the configuration file.

GlobalConfig : Similar to Config, but the Property of the subclass will read the value from the base class.

The saved ini file can be found in the project folder Config


Access parameters within the settings class

Use CDO to access configuration parameters

GetDefault<T>() can get const T*

GetMutableDefault<T>() can get T*, which can be used to modify the value in the Setting class

// 访问使用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;	
}

Guess you like

Origin blog.csdn.net/qq_25521145/article/details/127456680