How to add custom settings in Project Settings?

Hi. I’ve been trying to add a Custom Settings in Project Settings. I’ve found one tutorial on the web but it does not explain How do I get that data from it, How do I execute it to add on the project settings. It just shows the syntax lol. I’ve looked into the documentation and all my searches are just explaining the anatomy of the project settings in the editor. I may not know what specific word to search so maybe that’s why I can’t find it in the documentation.

Hi there RowelCaps What is the name of the tutorial that you have found on the web?
I’ll be happy to know since I want to add custom settings of my own to the project settings window.

Hi there!

I was able to accomplish this and I will do my best to explain what needs to be done, or at least what I did to get it to work. (I will also link my sources)

The first thing I did was follow these tutorials: Unreal Engine 4 adds custom settings to project settings - Programmer Sought + Plugins | Unreal Engine Documentation.

These tutorials show you how to create a plugin and how to set up your settings.

The plugin I created is called TestPlugin (.cpp/.h) and this is what the code looks like:

TestPlugin.h

// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

class FTestPluginModule : public IModuleInterface
{
public:

	/** IModuleInterface implementation */
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
};

TestPlugin.cpp

// Copyright Epic Games, Inc. All Rights Reserved.

#include "TestPlugin.h"
#include "TestPlugin_Settings.h"
#include "ISettingsModule.h"

#define LOCTEXT_NAMESPACE "FTestPluginModule"

void FTestPluginModule::StartupModule()
{
	// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module

	if(ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
	{
		SettingsModule->RegisterSettings("Project", "Plugins", "TestPlugin_Settings",
			LOCTEXT("RuntimeSettingsName", "My Setting Page"), LOCTEXT("RuntimeSettingsDescription", "Configure my setting"),
			GetMutableDefault<UTestPlugin_Settings>());
	}
}

void FTestPluginModule::ShutdownModule()
{
	// This function may be called during shutdown to clean up your module.  For modules that support dynamic reloading,
	// we call this function before unloading the module.

	if(ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings"))
	{
		SettingsModule->UnregisterSettings("Project", "Plugins", "TestPlugin_Settings");
	}
}

#undef LOCTEXT_NAMESPACE
	
IMPLEMENT_MODULE(FTestPluginModule, TestPlugin)

You also need to create a settings class (this class is referenced in the above code so make sure you have this as well before trying to compile anything). This settings class should derive from UObject, and in my case, I called it TestPlugin_Settings (.cpp/.h)

TestPlugin_Settings.h

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "TestPlugin_Settings.generated.h"

/**
 * 
 */
UCLASS(config = MySetting)
class TESTPLUGIN_API UTestPlugin_Settings : public UObject
{
	GENERATED_BODY()

public:
	UTestPlugin_Settings(const FObjectInitializer& obj);

	UPROPERTY(Config, EditAnywhere, Category = "My Custom Settings")
	bool CustomBoolFlag;

	UPROPERTY(Config, EditAnywhere, Category = "My Custom Settings")
	int32 CustomInteger;
};

TestPlugin_Settings.cpp

#include "TestPlugin/Public/TestPlugin_Settings.h"

UTestPlugin_Settings::UTestPlugin_Settings(const FObjectInitializer& obj)
{
	CustomBoolFlag = false;
	CustomInteger = 0;
}

After you have created these classes, you should then add the plugin to your .uproject file; here is mine: [Please ignore all other plugins except for “TestPlugin”]

	"Plugins": [
		{
			"Name": "GameplayAbilities",
			"Enabled": true
		},
		{
			"Name": "DarkerNodes",
			"Enabled": true,
			"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/4b3441f0228a40ec9ca986489a5bd682"
		},
		{
			"Name": "MagicNode",
			"Enabled": true,
			"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/38f49e7411bc47588e0d219758d6b16f"
		},
		{
			"Name": "ElectronicNodes",
			"Enabled": true,
			"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/5cb2a394d0c04e73891762be4cbd7216"
		},
		{
			"Name": "TestPlugin",
			"Enabled": true,
			"MarketplaceURL": ""
		}
	]

Now you should be able to recompile, and after its done you should have these accessible properties:

PluginsList

Now, in order to access these properties you need to do the following:

In your project’s build.cs file, you need to add the plugin. Here is mine:

// Copyright Epic Games, Inc. All Rights Reserved.
// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class Hero : ModuleRules
{
	public Hero(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

        PublicDependencyModuleNames.AddRange(new string[] { "GameplayAbilities", "GameplayTags", "GameplayTasks", "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "UMG", "Slate", "SlateCore", "AIModule", "TestPlugin"});

        MinFilesUsingPrecompiledHeaderOverride = 1;
        bUseUnity = true;
    }
}

Now for my example, I am logging these two settings in the Output Log when my player character is possessed. First, I need to include the plugin:

include “TestPlugin/Public/TestPlugin_Settings.h”

Then, I need to initialize a reference to the plugin. Again, I do this inside of the PossessedBy(AController* New Controller) function within my character:

UTestPlugin_Settings* Plugin_Settings = GetMutableDefault<UTestPlugin_Settings>();

if(Plugin_Settings->CustomBoolFlag)
{
UE_LOG(LogTemp, Warning, TEXT(“My Custom Bool = true”));
}
else
{
UE_LOG(LogTemp, Warning, TEXT(“My Custom Bool = false”));
}

UE_LOG(LogTemp, Warning, TEXT(“My Custom Integer = %i”), Plugin_Settings->CustomInteger);

Now you should be able to compile and when my character is spawned/possessed, the log prints out:

Log
Which matches the settings that I had earlier.

Here are my sources again that I used, and I hope this answers your question/was helpful. Good luck!

21 Likes

Hey! Sorry to bump an old topic but I have to ask - will this same setup work for a packaged plugin (i.e. if I want to reuse my plugin for multiple projects)? Or are there some extra steps that I have to take to make it work? Thanks.

Okay, so for anyone seeing this that may have the same issue. I wasn’t able to fix it using the ISettingsModule, but I stumbled upon what I assume is the currently intended way of doing it:
Having my settings not derive from UObject, but rather UDeveloperSettings.
For the categorization I just overrode the different getters for SectionName, SectionText etc.

Little note of caution for packaging:
GetSectionDescription() and GetSectionText() need to be wrapped in a #if WITH_EDITOR, just like in the UDeveloperSettings class.

3 Likes

This was amazing thank you!

1 Like

Using UDeveloperSettings makes my setting duplicated:
image

I fixed it by removing the module method above and using these codes:

Header:

#pragma once

#include "Engine/DeveloperSettings.h"
#include "CurrencySetting.generated.h"

UCLASS(config = CurrencySystem, DefaultConfig)
class CURRENCYSYSTEMRUNTIME_API UCurrencySetting : public UDeveloperSettings
{
	GENERATED_BODY()

public:
	UCurrencySetting();

	UPROPERTY(Config, EditAnywhere, meta = (ClampMin = "0", UIMin = "0"))
		int StartingAmount;
};

CPP:

#include "CurrencySetting.h"

UCurrencySetting::UCurrencySetting() : StartingAmount{}
{
	CategoryName = "Plugins";

	SectionName = "Currency System";
}

Result:

2 Likes

so by just creating a new class drived from UDeveloperSettings , i can get a new category ?
i have used the method above this and it worked by the settings i set are not reflected directly to the game they take some time before the values are correct

i have two TSubclassOf properties in my subsystem class which i used to be my settings object too, i wanted to set the class there and use them in my logics , and in my subsystem constrcutor i used them to create instances of them but i find them null but when i put a break point down the execution i find that the classes are no longer null , so is that means that the editor settings are loaded after the class constructor ? or how to do it by the book

You only need UDeveloperSettings, you don’t really need the module stuff.
SectionName won’t work by the way.

1 Like

oh thanks for the fast reply , i will use your way then and see if it helps , i see it a bit more organized than making things in editor module and stuff, sorry for disturbing

Indeed, setting the SectionName variable doesn’t seem to do anything.

However, the DisplayName meta property does change the config section name. For example like this:

UCLASS(Config=CurrencySystem, meta=(DisplayName="Currency System"))
class CURRENCYSYSTEMRUNTIME_API UCurrencySetting : public UDeveloperSettings
{ ... }

Picked this from Epic’s CollisionProfile.h :slight_smile:
Cheers!

1 Like

Hello! Can you please clarify, what did you mean by “fixed it by removing the module method above”?
What have you removed - I’m failing to see any major differences between your code and on the original answer. How did you manage to remove duplicating settings menu entries?

Don’t do anything that is mentioned as original answer (to add settings in module start up function). All you need to do is create a class derived from UDeveloperSettings and add variables to this class with Config property. Just follow How to add custom settings in Project Settings? - #10 by lehuan5062 answer.

By the way if anyone is having LNK error after creating UDeveloperSettings class, you need to add “DeveloperSettings” to Build.cs PrivateDependencyModuleNames section.

2 Likes

Thank you!

Hello!
I have done everything @DevinSherry said at the beginning of the post but nothing is showing up in the Plugin Editor. Can you help me? I don’t know what I’m doing wrong, I’m new to C++.

Hi, don’t follow beginning of the post, read my answer from Feb 29 (2 replies above your question). In short, just create class derived from UDeveloperSettings.

1 Like