Unresolved external symbol when compiling through VS, but not when compiling through Unreal Editor

UE Version: 4.8.3

VS Version: Visual Studio 2013 for Windows Desktop; 12.0.31101.00 Update 4

I’m seeing a weird issue and I’m not really sure how to get to the bottom of it. I’m new to UE4, and incredibly rusty with C++ (it’s been at least 10 years since I’ve used it). I’ve been referencing William Sherif’s Learning C++ by Creating Games with UE4 as a primer to get me up to speed.

The issue is that when I try to compile from VS, I get a couple of unresolved external symbols. If I compile from Unreal Editor, everything compiles and works just fine. I tried cleaning the project from VS, but the problem persists. I would have expected it to also fail to compile from Unreal Editor if there was something wrong with the code.

VS build output is below.

1>------ Build started: Project: GoldenEgg, Configuration: Development_Editor x64 ------
1>  Compiling game modules for hot reload
1>  Parsing headers for GoldenEggEditor
1>  Reflection code generated for GoldenEggEditor
1>  Performing 3 actions (4 in parallel)
1>  GoldenEgg.generated.cpp
1>  Avatar.cpp
1>  [3/3] Link UE4Editor-GoldenEgg-7418.dll
1>     Creating library F:\Unreal Projects\GoldenEgg\Intermediate/Build/Win64\UE4Editor\Development\UE4Editor-GoldenEgg-7418.lib and object F:\Unreal Projects\GoldenEgg\Intermediate/Build/Win64\UE4Editor\Development\UE4Editor-GoldenEgg-7418.exp
1>Avatar.cpp.obj : error LNK2019: unresolved external symbol "public: __cdecl AAvatar::AAvatar(class FObjectInitializer const &)" (??0AAvatar@@QEAA@AEBVFObjectInitializer@@@Z) referenced in function "public: static void __cdecl AAvatar::__DefaultConstructor(class FObjectInitializer const &)" (?__DefaultConstructor@AAvatar@@SAXAEBVFObjectInitializer@@@Z)
1>GoldenEgg.generated.cpp.obj : error LNK2001: unresolved external symbol "public: __cdecl AAvatar::AAvatar(class FObjectInitializer const &)" (??0AAvatar@@QEAA@AEBVFObjectInitializer@@@Z)
1>MyHUD.cpp.obj : error LNK2019: unresolved external symbol "public: __cdecl AMyHUD::AMyHUD(class FObjectInitializer const &)" (??0AMyHUD@@QEAA@AEBVFObjectInitializer@@@Z) referenced in function "public: void __cdecl AMyHUD::`default constructor closure'(void)" (??_FAMyHUD@@QEAAXXZ)
1>GoldenEgg.generated.cpp.obj : error LNK2001: unresolved external symbol "public: __cdecl AMyHUD::AMyHUD(class FObjectInitializer const &)" (??0AMyHUD@@QEAA@AEBVFObjectInitializer@@@Z)
1>F:\Unreal Projects\GoldenEgg\Binaries\Win64\UE4Editor-GoldenEgg-7418.dll : fatal error LNK1120: 2 unresolved externals
1>  -------- End Detailed Actions Stats -----------------------------------------------------------
1>ERROR : UBT error : Failed to produce item: F:\Unreal Projects\GoldenEgg\Binaries\Win64\UE4Editor-GoldenEgg-7418.dll
1>  Total build time: 20.07 seconds
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command ""F:\Epic Games\4.8\Engine\Build\BatchFiles\Build.bat" GoldenEggEditor Win64 Development "F:\Unreal Projects\GoldenEgg\GoldenEgg.uproject" -rocket" exited with code -1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Code:

Avatar.h

#pragma once

#include "GameFramework/Character.h"
#include "Avatar.generated.h"

UCLASS()
class GOLDENEGG_API AAvatar : public ACharacter
{
	GENERATED_UCLASS_BODY()

public:
	// Sets default values for this character's properties
	AAvatar();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;

	void MoveForward(float amount);
	void MoveBack(float amount);
	void MoveLeft(float amount);
	void MoveRight(float amount);
	void Yaw(float amount);
	void Pitch(float amount);
};

Avatar.cpp

#include "GoldenEgg.h"
#include "Avatar.h"


// Sets default values
AAvatar::AAvatar()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AAvatar::BeginPlay()
{
	Super::BeginPlay();
	
}

// Called every frame
void AAvatar::Tick( float DeltaTime )
{
	Super::Tick( DeltaTime );

}

// Called to bind functionality to input
void AAvatar::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
	Super::SetupPlayerInputComponent(InputComponent);

	check(InputComponent);
	InputComponent->BindAxis("Forward", this, &AAvatar::MoveForward);
	InputComponent->BindAxis("Back", this, &AAvatar::MoveBack);
	InputComponent->BindAxis("StrafeL", this, &AAvatar::MoveLeft);
	InputComponent->BindAxis("StrafeR", this, &AAvatar::MoveRight);
	InputComponent->BindAxis("Yaw", this, &AAvatar::Yaw);
	InputComponent->BindAxis("Pitch", this, &AAvatar::Pitch);
}

void AAvatar::MoveForward(float amount)
{
	if (Controller && amount)
	{
		FVector fwd = GetActorForwardVector();
		AddMovementInput(fwd, amount);
	}
}

void AAvatar::MoveBack(float amount)
{
	if (Controller && amount)
	{
		FVector back = -GetActorForwardVector();
		AddMovementInput(back, amount);
	}
}

void AAvatar::MoveLeft(float amount)
{
	if (Controller && amount)
	{
		FVector left = -GetActorRightVector();
		AddMovementInput(left, amount);
	}
}

void AAvatar::MoveRight(float amount)
{
	if (Controller && amount)
	{
		FVector right = GetActorRightVector();
		AddMovementInput(right, amount);
	}
}

void AAvatar::Yaw(float amount)
{
	AddControllerYawInput(200.f * amount * ()->GetDeltaSeconds());
}

void AAvatar::Pitch(float amount)
{
	AddControllerPitchInput(200.f * amount * ()->GetDeltaSeconds());
}

MyHUD.h

#pragma once

#include "GameFramework/HUD.h"
#include "MyHUD.generated.h"

/**
 * 
 */
UCLASS()
class GOLDENEGG_API AMyHUD : public AHUD
{
	GENERATED_UCLASS_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = HUDFont) UFont *hudFont;
	
	virtual void DrawHUD() override;
	
};

MyHUD.cpp

#include "GoldenEgg.h"
#include "MyHUD.h"


void AMyHUD::DrawHUD()
{
	Super::DrawHUD();

	DrawLine(200, 300, 400, 500, FLinearColor::Blue);
	DrawText("Testing", FVector2D(0, 0), hudFont, FVector2D(1, 1), FColor::White);
}

I think linking errors are related to constructors. GENERATED_UCLASS_BODY() generate constructor that is using FObjectInitializer mentioned by linker and you don’t have those in cpp. Try replacing GENERATED_UCLASS_BODY() to GENERATED_BODY() which don’t create constructor.

That solved the linking errors, but introduced a new one:

1>------ Build started: Project: GoldenEgg, Configuration: Development_Editor x64 ------
1>  Compiling game modules for hot reload
1>  Parsing headers for GoldenEggEditor
1>  F:/Unreal Projects/GoldenEgg/Source/GoldenEgg/MyHUD.h(17) : BlueprintReadWrite should not be used on private members
1>Error : Failed to generate code for GoldenEggEditor - error code: OtherCompilationError (5)
1>  UnrealHeaderTool failed for target 'GoldenEggEditor' (platform: Win64, module info: F:\Unreal Projects\GoldenEgg\Intermediate\Build\Win64\GoldenEggEditor\Development\UnrealHeaderTool.manifest).
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command ""F:\Epic Games\4.8\Engine\Build\BatchFiles\Build.bat" GoldenEggEditor Win64 Development "F:\Unreal Projects\GoldenEgg\GoldenEgg.uproject" -rocket" exited with code -1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

To fix the new error, I moved GENERATED_BODY() into the public: part of my class definitions. The project now compiles successfully both in Visual Studio and through Unreal Editor.

Thank you!

Add this to all C++ Class what has this ‘GENERATED_UCLASS_BODY()’
AAvatar::AAvatar(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
}