Deriving USoundCue in Plugin: From "undeclared identifier" to "unresolved external symbol"

Hi,
I’m quite new to UE, and while i’m allready loving it, i’m quite stuck. I’ve tought it would be a good idae to start with building a plugin, to learn to communicate with engine. In there, i want to create a new asset type derived from USoundCue.

So i hit the “Create Plugin” button in the Plugin Menü, messed a while around, updated to 4.12 and then, at some time, i encountered this one, when i hit the build button:

D:\private\UE4\Epic
Games\4.12\Engine\Source\Runtime\Engine\Classes\Sound/SoundAttenuation.h(230): error C2065: ‘ECC_Visibility’:
undeclared identifier

when trying this:

#pragma once
//#include "Engine/EngineTypes.h"
#include "Sound/SoundCue.h"
#include "eMuseSoundCue.generated.h"

UCLASS()
class UeMuseSoundCue : public USoundCue
{
	GENERATED_UCLASS_BODY()
	
public:
	UPROPERTY(EditAnywhere, Category = "eMuse Sound Cue Properties")
	FString Name;
	UeMuseSoundCue();
};

See the comment in the #includes? There the Enum is defined, so when including this line, i get:

Creating library C:\Users\Eleison\Documents\Unreal Projects\eMuseTestlab\Plugins\eMuse\Intermediate\Build\Win64\UE4Editor\DebugGame\UE4Editor-eMuse-Win64-DebugGame.lib and object C:\Users\Eleison\Documents\Unreal Projects\eMuseTestlab\Plugins\eMuse\Intermediate\Build\Win64\UE4Editor\DebugGame\UE4Editor-eMuse-Win64-DebugGame.exp
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual unsigned __int64 __cdecl USoundCue::GetResourceSize(enum EResourceSizeMode::Type)" (?GetResourceSize@USoundCue@@UEAA_KW4Type@EResourceSizeMode@@@Z)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual unsigned __int64 __cdecl USoundCue::GetResourceSize(enum EResourceSizeMode::Type)" (?GetResourceSize@USoundCue@@UEAA_KW4Type@EResourceSizeMode@@@Z)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual class FString __cdecl USoundCue::GetDesc(void)" (?GetDesc@USoundCue@@UEAA?AVFString@@XZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual class FString __cdecl USoundCue::GetDesc(void)" (?GetDesc@USoundCue@@UEAA?AVFString@@XZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::PostInitProperties(void)" (?PostInitProperties@USoundCue@@UEAAXXZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::PostInitProperties(void)" (?PostInitProperties@USoundCue@@UEAAXXZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::PostEditChangeProperty(struct FPropertyChangedEvent &)" (?PostEditChangeProperty@USoundCue@@UEAAXAEAUFPropertyChangedEvent@@@Z)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::PostEditChangeProperty(struct FPropertyChangedEvent &)" (?PostEditChangeProperty@USoundCue@@UEAAXAEAUFPropertyChangedEvent@@@Z)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::PostLoad(void)" (?PostLoad@USoundCue@@UEAAXXZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::PostLoad(void)" (?PostLoad@USoundCue@@UEAAXXZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::Serialize(class FArchive &)" (?Serialize@USoundCue@@UEAAXAEAVFArchive@@@Z)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::Serialize(class FArchive &)" (?Serialize@USoundCue@@UEAAXAEAVFArchive@@@Z)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl USoundCue::IsPlayable(void)const " (?IsPlayable@USoundCue@@UEBA_NXZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual bool __cdecl USoundCue::IsPlayable(void)const " (?IsPlayable@USoundCue@@UEBA_NXZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::Parse(class FAudioDevice *,unsigned __int64,struct FActiveSound &,struct FSoundParseParameters const &,class TArray<struct FWaveInstance *,class FDefaultAllocator> &)" (?Parse@USoundCue@@UEAAXPEAVFAudioDevice@@_KAEAUFActiveSound@@AEBUFSoundParseParameters@@AEAV?$TArray@PEAUFWaveInstance@@VFDefaultAllocator@@@@@Z)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual void __cdecl USoundCue::Parse(class FAudioDevice *,unsigned __int64,struct FActiveSound &,struct FSoundParseParameters const &,class TArray<struct FWaveInstance *,class FDefaultAllocator> &)" (?Parse@USoundCue@@UEAAXPEAVFAudioDevice@@_KAEAUFActiveSound@@AEBUFSoundParseParameters@@AEAV?$TArray@PEAUFWaveInstance@@VFDefaultAllocator@@@@@Z)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetVolumeMultiplier(void)" (?GetVolumeMultiplier@USoundCue@@UEAAMXZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetVolumeMultiplier(void)" (?GetVolumeMultiplier@USoundCue@@UEAAMXZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetPitchMultiplier(void)" (?GetPitchMultiplier@USoundCue@@UEAAMXZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetPitchMultiplier(void)" (?GetPitchMultiplier@USoundCue@@UEAAMXZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetMaxAudibleDistance(void)" (?GetMaxAudibleDistance@USoundCue@@UEAAMXZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetMaxAudibleDistance(void)" (?GetMaxAudibleDistance@USoundCue@@UEAAMXZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetDuration(void)" (?GetDuration@USoundCue@@UEAAMXZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual float __cdecl USoundCue::GetDuration(void)" (?GetDuration@USoundCue@@UEAAMXZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual struct FAttenuationSettings const * __cdecl USoundCue::GetAttenuationSettingsToApply(void)const " (?GetAttenuationSettingsToApply@USoundCue@@UEBAPEBUFAttenuationSettings@@XZ)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual struct FAttenuationSettings const * __cdecl USoundCue::GetAttenuationSettingsToApply(void)const " (?GetAttenuationSettingsToApply@USoundCue@@UEBAPEBUFAttenuationSettings@@XZ)
2>Module.eMuse.cpp.obj : error LNK2001: unresolved external symbol "public: virtual int __cdecl USoundCue::GetResourceSizeForFormat(class FName)" (?GetResourceSizeForFormat@USoundCue@@UEAAHVFName@@@Z)
2>eMuse.generated.cpp.obj : error LNK2001: unresolved external symbol "public: virtual int __cdecl USoundCue::GetResourceSizeForFormat(class FName)" (?GetResourceSizeForFormat@USoundCue@@UEAAHVFName@@@Z)
2>eMuse.generated.cpp.obj : error LNK2019: unresolved external symbol "public: static void __cdecl USoundCue::AddReferencedObjects(class UObject *,class FReferenceCollector &)" (?AddReferencedObjects@USoundCue@@SAXPEAVUObject@@AEAVFReferenceCollector@@@Z) referenced in function "private: static class UClass * __cdecl UeMuseSoundCue::GetPrivateStaticClass(wchar_t const *)" (?GetPrivateStaticClass@UeMuseSoundCue@@CAPEAVUClass@@PEB_W@Z)

So here, i got pretty sure that it’s probably not a issue with including single headers rather then a setup problem, so i went to the build.cs of my plugin and threw everything in there, what wasn’t able to get away in time:

eMuse.build.cs:

using UnrealBuildTool;    
public class eMuse : ModuleRules
{
	public eMuse(TargetInfo Target)
	{
		
		PublicIncludePaths.AddRange(
			new string[] {
				"eMuse/Public"
				// ... add public include paths required here ...
			}
			);
				
		
		PrivateIncludePaths.AddRange(
			new string[] {
				"eMuse/Private",
				// ... add other private include paths required here ...
			}
			);
			
		
		PublicDependencyModuleNames.AddRange(
			new string[]
			{
				"Core", "CoreUObject", "Engine",
                "Projects",
                "InputCore",
                "UnrealEd",
                "LevelEditor",
                "CoreUObject",
                "Engine",
                "Slate",
                "SlateCore",
                "UnrealEd", // for FAssetEditorManager
				"PropertyEditor",
                "ContentBrowser",
                "WorkspaceMenuStructure",
                "EditorStyle",
                "EditorWidgets"
				// ... add other public dependencies that you statically link with here ...
			}
			);
			
		
		PrivateDependencyModuleNames.AddRange(
			new string[]
			{
				"Projects",
				"InputCore",
				"UnrealEd",
				"LevelEditor",
				"CoreUObject",
				"Engine",
				"Slate",
				"SlateCore",
                "Core",
                "CoreUObject",
                "UnrealEd", // for FAssetEditorManager
				"PropertyEditor",
                "ContentBrowser",
                "WorkspaceMenuStructure",
                "EditorStyle",
                "EditorWidgets"
				// ... add private dependencies that you statically link with here ...	
			}
			);
		
		
		DynamicallyLoadedModuleNames.AddRange(
			new string[]
			{
				// ... add any modules that your module loads dynamically here ...
			}
			);
	}
}

After searching the net for days, i surrender now. I don’t even know where to look anymore, because i’m still not very confident with the build system of UE. I leave some more source here, mich i think may help:

eMusePrivate.PCH.h:

//#include "SlateBasics.h"
#include "eMuse.h"

eMuseSoundCue.cpp:

#include "eMusePrivatePCH.h"
#include "eMuseSoundCue.h"

// Sets default values
UeMuseSoundCue::UeMuseSoundCue(const FObjectInitializer& ObjectInitilizer)
	:Super(ObjectInitilizer)
{

}

UeMuseSoundCue::UeMuseSoundCue()
{
}

eMuse.uplugin:

    {
    	"FileVersion": 3,
    	"Version": 1,
    	"VersionName": "0.1",
    	"FriendlyName": "eMuse",
    	"Description": "tbd",
    	"

Category": "Visualization",
	"CreatedBy": "tbd",
	"CreatedByURL": "tbd",
	"DocsURL": "",
	"MarketplaceURL": "",
	"SupportURL": "",
	"EnabledByDefault": false,
	"CanContainContent": false,
	"IsBetaVersion": false,
	"Installed": false,
	"Modules": [
		{
			"Name": "eMuse",
			"Type": "Editor",
			"LoadingPhase": "Default"
		}
	]
}

And from the housing project:

eMuseTestlab.Build.cs:

public class eMuseTestlab : ModuleRules
{
	public eMuseTestlab(TargetInfo Target)
	{
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });
	}
}

eMuseTestLab.uproject:

{
	"FileVersion": 3,
	"EngineAssociation": "4.12",
	"Category": "",
	"Description": "",
	"Modules": [
		{
			"Name": "eMuseTestlab",
			"Type": "Runtime",
			"LoadingPhase": "Default",
			"AdditionalDependencies": [
				"Engine"
			]
		}
	],
	"Plugins": [
		{
			"Name": "SoundVisualizations",
			"Enabled": true
		}
	]
}

eMuseTestLab.h

#include "Engine.h"

I hope you can see the issue.

I’m on Win10, 64 bit with VS2015 Community.

Oh, and as a side note: When I created a class deriving from USoundCue with the c++ class wizzard to see, if i missed something in my hand written version, i also got the “unresolved externals” on that code inside the project.

Thanks in advance!

So basically, this seems to be an UE specific behaviour if i got right. Since this question didn’t arouse the expected attention, i did some more digging, trying workarounds and reading up different stuff about UE coding.

It just seems that the parts i trying to access in code are not meant to be accessed, since they are not marked with the related API macros. People, which also encounter this issue, change it themself and recompile the whole source, which seems a bit overkill to me, since i’m not working at engine level. I also want to avoid this, because i want to stay conform with the official base and not messing around at spots, i’m lacking the necessary understanding for yet. Besides that, they are not marked for a reason, right?

I’m trying to build a plugin, which gives more acces to sounds, with special assets and an related editor to them, while staying conform with SoundCue, so the assets can be used as such (think of an decorator system). If you have an idea, how i can achieve this, without changing the engine source, or point out, why i’m completely wrong, please leave a reply. Otherwise, i think i give cryengine and unity a shot.