Spawning an actor in C++ (this is probably quite easy, but I am badly stuck!)

Hi! I’ve been tinkering with the engine on & off for almost a year now. But there has always been one thing that kept me from going to C++ - spawning actors.
This time I decided to figure it out once and for all, and this is what I have currently:


void ARandomGenGameMode::CreateBlock(FVector Location)
{
	MyBlock = SpawnActor<ABlock>(Location, FRotator(0,0,0), NULL, Instigator, true);
}




This is a method (prob. not the technical name) I stole from Spawning Actors in Unreal Engine | Unreal Engine 5.2 Documentation "Spawn T Instance with Transform, Return T Pointer"There is nothing specific to this in .h file, not that they seem to tell you to do so in the documentation. I am getting " ‘MyBlock’ undeclared identifier “, ‘SpawnActor’ undeclared identifier " and " ‘ABlock’ illegal use of this type of expression”.

So, what am I missing? Thanks!

For one thing, have you declared MyBlock anywhere? If not, the compiler currently doesn’t know what it is, so try

ABlock * MyBlock = …

You may also have to include Block.h at the start of the file. Try that and see what errors you have left.

I have included block.h (in .cpp file), but when I hover over the “#include” I see " Error: cannot open source file “Block.h” “. Adding “ABlock *” does get rid of the first error, but ‘SpawnActor’ undeclared identifier " and " ‘ABlock’ illegal use of this type of expression” are still left.

Do you get an error when you compile about not being able to find include Block.h ? (not when you hover - ignore intellisense).

Also I’m not sure if “Instigator” is actually defined in the class. Try using “this” instead.

If you could post your code (.h and .cpp) for your ABlock and ARandomGenGameMode as well as the full error message that might speed things up.


Error: 1>------ Build started: Project: RandomGen, Configuration: Development_Editor x64 ------2>------ Skipped Build: Project: UE4, Configuration: BuiltWithUnrealBuildTool Win32 ------
2>Project not selected to build for this solution configuration 
1>  Compiling game modules for hot reload
1>  Parsing headers for RandomGenEditor
1>  Reflection code generated for RandomGenEditor
1>  Performing 2 actions (4 in parallel)
1>  RandomGenGameMode.cpp
1>C:\Users\me\Documents\Unreal Projects\RandomGen\Source\RandomGen\RandomGenGameMode.cpp(27): error C2065: 'SpawnActor' : undeclared identifier
1>C:\Users\me\Documents\Unreal Projects\RandomGen\Source\RandomGen\RandomGenGameMode.cpp(27): error C2275: 'ABlock' : illegal use of this type as an expression
1>          C:\Users\me\Documents\Unreal Projects\RandomGen\Source\RandomGen\Public\Block.h(9) : see declaration of 'ABlock'
1>  -------- End Detailed Actions Stats -----------------------------------------------------------
1>ERROR : UBT error : Failed to produce item: C:\Users\me\Documents\Unreal Projects\RandomGen\Binaries\Win64\UE4Editor-RandomGen-5782.dll
1>  Total build time: 13.19 seconds
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.MakeFile.Targets(38,5): error MSB3073: The command ""C:\Program Files\Unreal Engine\4.8\Engine\Build\BatchFiles\Build.bat" RandomGenEditor Win64 Development "C:\Users\me\Documents\Unreal Projects\RandomGen\RandomGen.uproject" -rocket" exited with code -1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 1 skipped ==========

Block.h:


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


#pragma once


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


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


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


	
	
	
};




block.cpp:


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


#include "RandomGen.h"
#include "Block.h"




// Sets default values
ABlock::ABlock()
{
 	// Set this actor 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 ABlock::BeginPlay()
{
	Super::BeginPlay();
	
}


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


}


RandomGenGameMode.h:


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


#pragma once


#include "GameFramework/GameMode.h"
#include "RandomGenGameMode.generated.h"
/**
 * 
 */
UCLASS()
class RANDOMGEN_API ARandomGenGameMode : public AGameMode
{
	GENERATED_BODY()


	virtual void BeginPlay() override;
	void CreateBlock(FVector Location);
	int16 Y = 0;
	
};




RandomGenGameMode.cpp:


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


#include "RandomGen.h"
#include "RandomGenGameMode.h"
#include "Engine.h"
#include "Block.h"




void ARandomGenGameMode::BeginPlay()
{
	Super::BeginPlay();


	






	for (int16 length = 0; length < 6;)
	{
		CreateBlock(FVector(length, Y, 0));
		length += 1;
	}


}


void ARandomGenGameMode::CreateBlock(FVector Location)
{
	ABlock * MyBlock = SpawnActor<ABlock>(Location, FRotator(0,0,0), NULL, this, true);
}


There you go!

That all looks ok to me. Unfortunately I’m at work so can’t test things, but I’d be interested to know if it compiles if you remove the SpawnActor line.

First of all, to use the SpawnActor method, you should access it through GetWorld. There are several examples in the UE4 code, look at the GameMode.cpp::SpawnPlayerController function.

Second, look at the parameters required in SpawnActor, the first parameter should be the class you want to instantiate. For your case it is a class of type ABlock,
you can’t use ABlock as the class type, ABlock is used to store objects of such class. In order to get the class type use the method



ABlock::StaticClass()


I recommend you to read the documentation, in this section you can read again all what I have described above

https://docs.unrealengine.com/latest/INT/API/Runtime/Engine/Engine/UWorld/SpawnActor/4/index.html
Cheers

I also think you did not declare “MyBlock” somewhere. If you want to save the reference of the spawned actor there, you need to give it a type first.


ABlock* MyBlock = GetWorld()->SpawnActor<ABlock>(ABlock::StaticClass(), POSITION, ROTATION, SPAWNPARAMETER);

And SPAWNPARAMETER is of type “FActorSpawnParameters”

Here is an example on how i spawn my Actor (without a position, only the class and the Parameter):


FActorSpawnParameters SpawnParams;

SpawnParams.bNoCollisionFail = true;

ABase_Item* Temp_Item = GetWorld()->SpawnActor<ABase_Item>(CraftingQueue[_QueueSlot]->ItemsNeeded*.ItemClass, SpawnParams);

And here is an example on how to spawn it with location and rotation:


FActorSpawnParameters SpawnParams;

		SpawnParams.bNoCollisionFail = true;

		ABase_Item* Temp_Item = GWorld->SpawnActor<ABase_Item>(_TreeDrop.ItemToDrop, GetActorLocation() + FVector(0,150,200), FRotator(0, 0, 0), SpawnParams);

In both cases, the first Parameter is the StaticClass of “ABase_Item”. In your code it would be the StaticClass of ABlock. Second Parameter is the Position, third Parameter is the Rotation and the last one is the SpawnParameter.

The SpawnParameter have different thing you can set (also an instigator). Just create a “FActorSpawnParameters SpawnParams” variable and check the available settings with “SpawnParams.”

Thank you eXi, thank you so much, from the bottom of my heart! Spawning actors has, to me, always been the symbol of how hard it is to move on to C++ (coming from Unity, I prefer the text based stuff greatly), and now thanks to you, stuff is actually being spawned :D. Maybe this + some hard work will give me enough foothold to finally conquer this more efficient way of getting things done :stuck_out_tongue:

If you are coming from Unity, i would highly recommend you to learn some basic C++ first. Otherwise you will always try to apply your C# knowledge, which is just not working here.