Introduction to UE4 Programming Part 14 help

Having an issue w/ what the author writes for the end of the SpawnPickup() function of the SpawnVolume.cpp file. Not really sure on how to resolve the error it keeps giving me:

SpawnVolume.h


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

#pragma once

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

/**
 * 
 */
UCLASS()
class TUTORIALCODE_API ASpawnVolume : public AActor
{
	GENERATED_BODY()
	
	/* BoxComponent to specify the spawning area within the level*/
	UPROPERTY(VisibleInstanceOnly, Category = Spawning)
	class UBoxComponent* WhereToSpawn;

	/* The Pickup to spawn*/
	UPROPERTY(EditAnywhere, Category = Spawning)
	class APickup* WhatToSpawn;
	
public:

	/* Minimum spawn delay*/
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spawning)
	float SpawnDelayRangeLow;

	/* Maximum spawn delay */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Spawning)
	float SpawnDelayRangeHigh;

	/* Finds a random point within the box component */
	UFUNCTION(BlueprintPure, Category = Spawning)
	FVector GetRandomPointInVolume();

	ASpawnVolume(const FObjectInitializer& ObjectInitializer);

	FORCEINLINE class UBoxComponent* GetWhereToSpawn() const { return WhereToSpawn; }
	FORCEINLINE class APickup* GetWhatToSpawn() const { return WhatToSpawn; }

private:

	/* Calculates a random spawn delay */
	float GetRandomSpawnDelay();

	/* The current spawn delay */
	float SpawnDelay;

	/* Handles the spawning of a new pickup */
	void SpawnPickup();
};

SpawnVolume.cpp


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

#include "TutorialCode.h"
#include "SpawnVolume.h"
#include "Pickup.h"

ASpawnVolume::ASpawnVolume(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	// Create the simple StaticMeshComponent to represent the pickup in the level
	WhereToSpawn = ObjectInitializer.CreateDefaultSubobject<UBoxComponent>(this, TEXT("WhereToSpawn"));

	// Set the StaticMeshComponent as the root component
	RootComponent = WhereToSpawn;

	// Set the spawn delay range and get the first spawndelay
	SpawnDelayRangeLow = 1.0f;
	SpawnDelayRangeHigh = 4.5f;
	SpawnDelay = GetRandomSpawnDelay();
}

void ASpawnVolume::SpawnPickup()
{
	// If we have set something to spawn:
	if (WhatToSpawn != NULL)
	{
		// Check for 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 for the spawned item
			FRotator SpawnRotation;
			SpawnRotation.Yaw = FMath::FRand() * 360.f;
			SpawnRotation.Pitch = FMath::FRand() * 360.f;
			SpawnRotation.Roll = FMath::FRand() * 360.f;

			// spawn the pickup
			APickup* const SpawnedPickup = World->SpawnActor<APickup>(WhatToSpawn, SpawnLocation, SpawnRotation, SpawnParams);
		}
	}
}

float ASpawnVolume::GetRandomSpawnDelay()
{
	// Get a random float that falls within the spawn delay range
	return FMath::FRandRange(SpawnDelayRangeLow, SpawnDelayRangeHigh);
}

FVector ASpawnVolume::GetRandomPointInVolume()
{
	FVector RandomLocation;
	float MinX, MinY, MinZ;
	float MaxX, MaxY, MaxZ;

	FVector Origin;
	FVector BoxExtent;

	// Get the spawn volume's origin and box extent
	Origin = WhereToSpawn->Bounds.Origin;
	BoxExtent = WhereToSpawn->Bounds.BoxExtent;

	// Calculate the minimum X, Y, and Z
	MinX = Origin.X - BoxExtent.X / 2.f;
	MinY = Origin.Y - BoxExtent.Y / 2.f;
	MinZ = Origin.Z - BoxExtent.Z / 2.f;

	// Calculate the maximum X, Y, and Z
	MaxX = Origin.X + BoxExtent.X / 2.f;
	MaxY = Origin.Y + BoxExtent.Y / 2.f;
	MaxZ = Origin.Z + BoxExtent.Z / 2.f;

	// The random spawn location will fall between the min and max X, Y, and Z
	RandomLocation.X = FMath::FRandRange(MinX, MaxX);
	RandomLocation.Y = FMath::FRandRange(MinY, MaxY);
	RandomLocation.Z = FMath::FRandRange(MinZ, MaxZ);

	// Return the random spawn location
	return RandomLocation;
}

The error:

error C2664: ‘T *UWorld::SpawnActor<APickup>(UClass *,const FVector &,const FRotator &,const FActorSpawnParameters &)’ : cannot convert argument 1 from ‘APickup *’ to ‘UClass *’
1> with
1>
1> T=APickup
1> ]
1> Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

You need to get the class of the instance WhatToSpawn is pointing to. In SpawnActor try WhatToSpawn->GetClass()

To elaborate a bit on HammelGammel’s reply,



	/* The Pickup to spawn*/
	UPROPERTY(EditAnywhere, Category = Spawning)
	class APickup* WhatToSpawn;


This is a pointer to an instance of APickup, not a class of APickup. Even if you try using GetClass on it, you’ll have a hard time specifying an instance since it is not spawned to begin with. Replace that property with:



	/* The Pickup to spawn*/
	UPROPERTY(EditAnywhere, Category = Spawning)
	TSubclassOf<class APickup> WhatToSpawn;


This will allow you to specify the class you want to spawn, and incidentally will fix your compilation error.

You’re absolutely right. TSubclassOf makes more sense here. I should have pointed that out yesterday.

That did it! Thank you so much ! After replacing the pointer w/ the TSubClassOf, it compiled w/o error. I didn’t even know that existed :). Still learning the API and C++…