Download

Compilation error when following along with Unreal's C++ Tutorials

So I’ve been following along with unreal’s C++ tutorial “3rd Person Powerup Game with C++” but I’ve hit a snag. I don’t quite understand the error being reported by visual studio and I was wondering if anyone could help me out. The problem only occurs whenever I try and define SpawnPickup function in SpawnVolume.cpp. Here is the code headers and source files I’m using:

PickUp.h


#pragma once

#include "GameFramework/Actor.h"
#include "PickUp.generated.h"

UCLASS()
class ANOTHERBATTERY_API APickUp : public AActor
{
	GENERATED_BODY()

public:
	// Sets default values for this actor's properties
	APickUp();

	// Called when the game starts or when spawned
	void BeginPlay() override;

	// Called every frame
	virtual void Tick(float DeltaSeconds) override;

	/* Return the mesh for the pickup */
	FORCEINLINE	class UStaticMeshComponent* GetMesh() const { return PickupMesh; }

	// Return whether or not pickup is active
	UFUNCTION(BlueprintPure, Category = "Pickup")
		bool IsActive();

	/* Allows other classes to safely change whether or not pickup is active */
	UFUNCTION(BlueprintCallable, Category = "Pickup")
		void SetActive(bool NewPickupState);

protected:
	/* True when pickup is used and false when pickup is deactivated */
	bool bIsActive;

private:
	//** Static Mesh to represent the pickup in the level **//
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Pickup", meta = (AllowPrivateAccess = "true"))
	class UStaticMeshComponent* PickupMesh;

};


PickUp.cpp


#include "AnotherBattery.h"
#include "PickUp.h"


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

	// All Pickups start active
	bIsActive = true;

	//Create the static mesh component
	PickupMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("PickupMesh"));
	RootComponent = PickupMesh;

}

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

}

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

}

// Returns active state
bool APickUp::IsActive()
{
	return bIsActive;
}

// Changes active state
void APickUp::SetActive(bool NewPickupState)
{
	bIsActive = NewPickupState;
}

SpawnVolume.h


#pragma once

#include "GameFramework/Actor.h"
#include "SpawnVolume.generated.h"

UCLASS()
class ANOTHERBATTERY_API ASpawnVolume : public AActor
{
	GENERATED_BODY()
	
public:
	// Sets default values for this actor's properties
	ASpawnVolume();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

	// Called every frame
	virtual void Tick(float DeltaSeconds) override;

	// Returns the wheretoSpawn subobject
	FORCEINLINE class UBoxComponent* GetWhereToSpawn() const { return WhereToSpawn; }

	UFUNCTION(BlueprintPure, Category = "Spawning")
		FVector GetRandomPointInVolume();

protected:
	//The pickup to spawn
	UPROPERTY(EditAnywhere, Category = "Spawning")
		TSubclassOf<class APickup> WhatToSpawn;

private:
	// Box Component to specify where pickups should be spawned
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Spawning", meta = (AllowPrivateAccess = "true"))
	class UBoxComponent* WhereToSpawn;

	// Handle Spawning a new pickup
	void SpawnPickup();

};

SpawnVolume.cpp


#include "AnotherBattery.h"
#include "SpawnVolume.h"
#include "Kismet/KismetMathLibrary.h"
#include "PickUp.h"


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

	// Create the Box Component to represent the spawn volume
	WhereToSpawn = CreateDefaultSubobject<UBoxComponent>(TEXT("WhereToSpawn"));
	RootComponent = WhereToSpawn;

}

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

}

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

}

FVector ASpawnVolume::GetRandomPointInVolume()
{
	FVector SpawnOrigin = WhereToSpawn->Bounds.Origin;
	FVector SpawnExtend = WhereToSpawn->Bounds.BoxExtent;

	return UKismetMathLibrary::RandomPointInBoundingBox(SpawnOrigin, SpawnExtend);
}

void ASpawnVolume::SpawnPickup()
{
	// If we have set something to spawn:
	if (WhatToSpawn != NULL)
	{
		//check for a valid world
		UWorld * const World = GetWorld();
		if (World)
		{
			// Set the spawn parameters
			FActorSpawnParameters SpawnParams;
			SpawnParams.Owner = this;
			SpawnParams.Instigator = Instigator;

			// Get a random location to spawn at
			FVector SpawnLocation = GetRandomPointInVolume();

			//Get a random rotation from the spawned item
			FRotator SpawnRotation;
			SpawnRotation.Yaw = FMath::FRand() * 360.0f;
			SpawnRotation.Pitch = FMath::FRand() * 360.0f;
			SpawnRotation.Roll = FMath::FRand() * 360.0f;

			//Spawn the pickup
			World->SpawnActor<APickup>(WhatToSpawn, SpawnLocation, SpawnRotation, SpawnParams);
		}
	}
}

and here is the output log:

1>------ Skipped Build: Project: UE4, Configuration: BuiltWithUnrealBuildTool Win32 ------
1>Project not selected to build for this solution configuration
2>------ Build started: Project: AnotherBattery, Configuration: Development_Editor x64 ------
2> Compiling game modules for hot reload
2> Performing 2 actions (4 in parallel)
2> SpawnVolume.cpp
2>C:\Program Files\Epic Games\4.9\Engine\Source\Runtime\CoreUObject\Public\UObject\Class.h(2657): error C2027: use of undefined type ‘APickup’
2> c:\users\jason\documents\unreal projects\anotherbattery\source\anotherbattery\SpawnVolume.h(32) : see declaration of ‘APickup’
2> C:\Program Files\Epic Games\4.9\Engine\Source\Runtime\CoreUObject\Public\UObject\Class.h(2656) : while compiling class template member function ‘UClass *TSubclassOf<APickup>::operator *(void) const’
2> C:\Program Files\Epic Games\4.9\Engine\Source\Runtime\CoreUObject\Public\UObject\ObjectBase.h(1655) : see reference to function template instantiation ‘UClass *TSubclassOf<APickup>::operator *(void) const’ being compiled
2> c:\users\jason\documents\unreal projects\anotherbattery\source\anotherbattery\SpawnVolume.h(32) : see reference to class template instantiation ‘TSubclassOf<APickup>’ being compiled
2>C:\Program Files\Epic Games\4.9\Engine\Source\Runtime\CoreUObject\Public\UObject\Class.h(2657): error C3861: ‘StaticClass’: identifier not found
2> -------- End Detailed Actions Stats -----------------------------------------------------------
2>ERROR : UBT error : Failed to produce item: C:\Users\Jason\Documents\Unreal Projects\AnotherBattery\Binaries\Win64\UE4Editor-AnotherBattery-4015.dll
2> Total build time: 2.35 seconds
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command ““C:\Program Files\Epic Games\4.9\Engine\Build\BatchFiles\Build.bat” AnotherBatteryEditor Win64 Development “C:\Users\Jason\Documents\Unreal Projects\AnotherBattery\AnotherBattery.uproject” -rocket -waitmutex” exited with code -1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 1 skipped ==========

Looks like a case sensitivity issue with APickup. You’ve defined it as APickUp in PickUp.h, but using APickup in in SpawnVolume.h/cpp. Change it to APickUp in SpawnVolume.h/cpp.

Oh wow thank you. I would have never caught that. The compiler usually catches those errors but I guess since I did a forward declaration of APickup it just showed up like a normal class in visual studio. Thanks again!