Download

Trying to add settings class to plugin

I’m trying to add a new AActor class or UEditorSettings class to a plugin. This fails to compile, badly.

I first tried just writing code I knew should work, then I generated it from inside the Unreal Editor. Both setups fail once I relocate the two files to live inside the plugin. Is the issue that I’m trying to include this class in a plugin?

Example:


#pragma once

#include "Settings/EditorSettings.h"
#include "MySettings.generated.h"


/**
 * 
 */
UCLASS(Config=Engine)
class MYPLUGIN_API UMySettings : public UEditorSettings
{
    GENERATED_BODY()


    FString MyUsername;
    FString MyPassword;
};


1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class UObjectBase * __cdecl FUObjectAllocator::AllocateUObject(int,int,bool)" (__imp_?AllocateUObject@FUObjectAllocator@@QEAAPEAVUObjectBase@@HH_N@Z) referenced in function "void __cdecl GetPrivateStaticClassBody<class UMySettings>(wchar_t const *,wchar_t const *,class UClass * &,void (__cdecl*)(void))" (??$GetPrivateStaticClassBody@VUMySettings@@@@YAXPEB_W0AEAPEAVUClass@@P6AXXZ@Z)1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class UPackage * __cdecl GetTransientPackage(void)" (__imp_?GetTransientPackage@@YAPEAVUPackage@@XZ) referenced in function "public: static class UObject * __cdecl UMySettings::__VTableCtorCaller(class FVTableHelper &)" (?__VTableCtorCaller@UMySettings@@SAPEAVUObject@@AEAVFVTableHelper@@@Z)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class UObject * __cdecl StaticFindObjectFast(class UClass *,class UObject *,class FName,bool,bool,enum EObjectFlags)" (__imp_?StaticFindObjectFast@@YAPEAVUObject@@PEAVUClass@@PEAV1@VFName@@_N3W4EObjectFlags@@@Z) referenced in function "class UPackage * __cdecl Z_Construct_UPackage_MyPlugin(void)" (?Z_Construct_UPackage_MyPlugin@@YAPEAVUPackage@@XZ)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class UObject * __cdecl StaticFindObject(class UClass *,class UObject *,wchar_t const *,bool)" (__imp_?StaticFindObject@@YAPEAVUObject@@PEAVUClass@@PEAV1@PEB_W_N@Z) referenced in function "class UClass * __cdecl FindObject<class UClass>(class UObject *,wchar_t const *,bool)" (??$FindObject@VUClass@@@@YAPEAVUClass@@PEAVUObject@@PEB_W_N@Z)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class UPackage * __cdecl FindPackage(class UObject *,wchar_t const *)" (__imp_?FindPackage@@YAPEAVUPackage@@PEAVUObject@@PEB_W@Z) referenced in function "void __cdecl GetPrivateStaticClassBody<class UMySettings>(wchar_t const *,wchar_t const *,class UClass * &,void (__cdecl*)(void))" (??$GetPrivateStaticClassBody@VUMySettings@@@@YAXPEB_W0AEAPEAVUClass@@P6AXXZ@Z)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) class UObject * __cdecl StaticAllocateObject(class UClass *,class UObject *,class FName,enum EObjectFlags,bool,bool *)" (__imp_?StaticAllocateObject@@YAPEAVUObject@@PEAVUClass@@PEAV1@VFName@@W4EObjectFlags@@_NPEA_N@Z) referenced in function "public: static void * __cdecl UMySettings::operator new(unsigned __int64,enum EInternal,class UObject *,class FName,enum EObjectFlags)" (??2UMySettings@@SAPEAX_KW4EInternal@@PEAVUObject@@VFName@@W4EObjectFlags@@@Z)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl UObjectForceRegistration(class UObjectBase *)" (__imp_?UObjectForceRegistration@@YAXPEAVUObjectBase@@@Z) referenced in function "class UClass * __cdecl Z_Construct_UClass_UMySettings(void)" (?Z_Construct_UClass_UMySettings@@YAPEAVUClass@@XZ)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl InitializePrivateStaticClass(class UClass *,class UClass *,class UClass *,wchar_t const *,wchar_t const *)" (__imp_?InitializePrivateStaticClass@@YAXPEAVUClass@@00PEB_W1@Z) referenced in function "void __cdecl GetPrivateStaticClassBody<class UMySettings>(wchar_t const *,wchar_t const *,class UClass * &,void (__cdecl*)(void))" (??$GetPrivateStaticClassBody@VUMySettings@@@@YAXPEB_W0AEAPEAVUClass@@P6AXXZ@Z)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl UClassCompiledInDefer(struct FFieldCompiledInInfo *,wchar_t const *,unsigned __int64,unsigned int)" (__imp_?UClassCompiledInDefer@@YAXPEAUFFieldCompiledInInfo@@PEB_W_KI@Z) referenced in function "public: __cdecl TClassCompiledInDefer<class UMySettings>::TClassCompiledInDefer<class UMySettings>(wchar_t const *,unsigned __int64,unsigned int)" (??0?$TClassCompiledInDefer@VUMySettings@@@@QEAA@PEB_W_KI@Z)
1>MyPlugin.generated.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl UObjectCompiledInDefer(class UClass * (__cdecl*)(void),wchar_t const *)" (__imp_?UObjectCompiledInDefer@@YAXP6APEAVUClass@@XZPEB_W@Z) referenced in function "public: __cdecl FCompiledInDefer::FCompiledInDefer(class UClass * (__cdecl*)(void),wchar_t const *)" (??0FCompiledInDefer@@QEAA@P6APEAVUClass@@XZPEB_W@Z)


I’ve pretty much followed the directions here but it still fails: UCLASS definition inside a project plugin - how to make it work? - C++ Gameplay Programming - Unreal Engine Forums

Just as a fun aside, I also get this from time to time as well:


1>Error : Failed to generate code for MyProjectEditor - error code: OtherCompilationError (5)

There doesn’t seem to be a good reason for why this happens on Google but I assume it’s the same problem at play or an issue with a macro or something.

If you want to include any editor based classes such as UEditorSettings. Then make sure your Build.cs has UnrealEd included in the PrivateDependencyModuleNames list. As for AActor, it should be enough to just have Engine. But it may worth making sure you have Core, CoreUObject as well.

Ah of course. Completely forgot about that. Thank you!

So my next question is: how do you actually trigger the save? Does it just happen?

I have a slate widget which writes back to the USettings object I instantiated. Does that automatically save itself somewhere? I’ve been searching my various Config directories for the right string but no joy so far.

Okay, new plan. I’m going to try using the UProperty class. Does that make sense? Would GConfig be a better choice?

And just an FYI, there is major google search collision between the UProperty class and the UPROPERTY() macro.

GConfig worked great! Is there any way to change the ini file being written to one shared by all projects?

I use GConfig in my own project to load specific data from a specific INI. Not sure about shared by all projects though. But I guess if you made a Base version of the ini in the engine directory, then that will be copied and used by each project.

Firstly I call "FConfigCacheIni::LoadGlobalIniFile(FinalIniName, IniFilename)" IniFilename contains the INI file I want to load (Without Base, Default, etc.) and the FinalIniName is the name to use when you want to read values from the config via GConfig->Get functions. Then you create a Default version of the ini in the Game config directory (and as I said above, if you want to use it for multiple projects, im guessing a Base version in the engine config directory)

Thanks for the reply again!

That wasn’t exactly what I was after as the directory it returns isn’t global to all projects, but it put me on the right track!



FString IniFile = FPaths::Combine(*FPaths::EngineUserDir(), *FString("Saved/Config"), (TCHAR*)*FPlatformProperties::IniPlatformName(), *FString("EditorSettings.ini"));
GConfig->SetString(TEXT("MyPlugin"), TEXT("Username"), *Username, IniFile);
GConfig->Flush(true, IniFile);


The path it gives me back is:


C:/Users/justin/AppData/Local/UnrealEngine/4.8/Saved/Config/Windows/EditorSettings.ini

This works exactly as required!

Yeah wasn’t entirely sure if it would end up global, as I only use the config for one project. But glad to see you found the way to do it.