Spawning Actors

I’ve been pulling my hair out over this for a few hours now and can’t seem to get my head around why it wont work. Basically, I setup a blank level and create a blueprint that holds a static mesh (sphere). I am then looking to spawn this object through C++ code so that it appears in my scene at a given location for now.

Looking at the documentation, spawn actor seems like the best way to do this, so I created an actor class and added this which I found looking around on the forum:


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

	static ConstructorHelpers::FObjectFinder<UBlueprint> MyBlueprint(TEXT("/Game/Blueprints/Ball"));

	if (GetWorld())
	{
		FActorSpawnParameters SpawnInfo;
		SpawnInfo.bNoCollisionFail = true;
		ASpawnCreator* itemBase = GetWorld()->SpawnActor<ASpawnCreator>(MyBlueprint, SpawnInfo);
	}

}

Now this throws errors due to MyBluePrint not being a correct parameter (which makes sense because it asks for a UClass static mesh, but even when supplying this (Ball::StaticClass() the function doesn’t seem to do anything).

Now I know this should be ridiculously simple (hopefully) but I can’t seem to get my head around it at all? So does anyone have a step-by-step, basic explanation of how to go about this, because the documentation just sends me in circles.

Thanks


static ConstructorHelpers::FObjectFinder<UClass> MyBlueprint(TEXT("Class'/Game/Blueprints/Ball.Ball_C'"));

Should work.
You’re trying to pass UBlueprint in SpawnActor, while it takes UClass.

Doesn’t seem to work either. Even casting it to a UClass pointer, which the function should be accepting as a first parameter, I get the error:

… : cannot convert argument 1 from ‘ConstructorHelpers::FObjectFinder<UClass *>’ to ‘UClass *’…

I feel I’m doing something stupid somewhere but it’s driving me up the wall.


static ConstructorHelpers::FObjectFinder<UClass> PlayerPawnBPClass(TEXT("Class'/Game/Blueprints/MyCharacter.MyCharacter_C'"));
if (PlayerPawnBPClass.Object != NULL)
{
	DefaultPawnClass = PlayerPawnBPClass.Object;
}

Taken directly from third-person template.
What error does compiler produce?
Also, that’s not really clear what you’re trying to do, is Ball blueprint’s base-class is ASpawnCreator? If not, you’re trying to spawn actor of ASpawnCreator, but passing another class.
Upd: Oh sorry, just noticed i forgot to mention that you have to pass MyBlueprint.Object, didn’t even notice that when copied code from template…

For now I was just trying to get the SpawnCreator class to spawn another instance of itself to see if I could even get that working. However, how would I go about making the Ball’s blueprint base class a ASpawnCreator and I will then try and pass the .Object of the class in.

Thanks

Just open your Ball blueprint, go to File and select Reparent Blueprint, then choose ASpawnCreator. You should successfully compile project DLL so editor would load that class and allow you to choose it. You’re also able to select base class for blueprint when creating it, just make sure to click “Custom Classes” at the bottom.

I’ve reparented the blueprint and all is compiling correctly, however I get a message box saying it failed to find Game/Blueprints/Ball. I’ve also used several variations of the string to find the asset but it doesn’t seem to find it at all. I have tried following some of the answers from this thread but I either get lost when people mention functions such as:



void name(TSubclassOf<ClassOfBlueprint> parameter)
{
   ClassOfBlueprint* effect = ConstructObject<ClassOfBlueprin>(parameter);
}

which to me wont do anything really to get the actual blueprint, along with the way they say to use spawn actor



FActorSpawnParameters SpawnInfo;
SpawnInfo.bNoCollisionFail = true;
ARPGItem* itemBase = GetWorld()->SpawnActor<ARPGItem>(item, SpawnInfo);


which again isn’t very useful from what they have mentioned before. I’m sure this should be a simple process but I’m amazed there is very little information (especially in the official docs which uses a SpawnActor function that I can’t even see in the function overload list in Visual Studio) and I’m slowly frying my mind in wondering why it won’t work.

If you use string similar to this

It should work, just make sure it is located at the specified path. I suggest you to check all available game samples, though you might not need the blueprint-based ones, there’s a lot of useful code snippets covering basic game stuff like spawning actors, making them move etc.


StrategyGame\Source\StrategyGame\Private\AI\StrategyAIDirector.cpp

pretty much covers everything you need to know about spawning.
Update: it might be wrong trying to spawn actor of the same type inside itself. I assume current situation will end up like this: you create first ever object of type ASpawnerActor, it will spawn another one during creation, the one it spawned will create another and so on…
It would be better for you to create separate actor class for that Ball blueprint, like ABall, add required components to it in the constructor and then simply pass ABall::StaticClass() to SpawnActor function. I actually don’t see a profit using blueprint for that kind of “feature”. Sorry for confusing you at first.

I think part of the issue may be the reference for your ball Blueprint - it’s often easiest to right-click on the Blueprint in the Content Browser and “Copy Reference”. Also, putting an asset reference like this in code may make things more difficult to change in the long run, if you change your mind about which Blueprint to spawn, and so it’s usually a good idea to expose a variable to the editor for setting Blueprint references like this. We definitely want to address spawning Actors in more depth in future documentation, but take a look at this code sample in the meantime. It does have the hard-coded reference, but also allows you to override the variable value in the editor.

ThingToSpawn is my Blueprint I want to spawn, and this class is SpawnHandler. Also, this is set up so you can set the spawn location and rotation, but if you omit those arguments from SpawnActor (AActor const SpawningObject = World->SpawnActor<AActor>(WhatToSpawn, SpawnParams);*), it will just spawn your Blueprint Actor at the origin.

SpawnHandler.h



// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#pragma once

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

/**
 * 
 */
UCLASS()
class ASpawnHandler : public AActor
{
    GENERATED_UCLASS_BODY()

    virtual void BeginPlay() OVERRIDE;

    /** Projectile class to spawn */
    UPROPERTY(EditAnywhere, Category = General)
    TSubclassOf<class AActor> WhatToSpawn;

    UPROPERTY(EditAnywhere, Category = Location)
    FVector SpawnLocation;

    UPROPERTY(EditAnywhere, Category = Location)
    FRotator SpawnRotation;
    
};


SpawnHandler.cpp



// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.

#include "SpawnActor.h"
#include "SpawnHandler.h"


ASpawnHandler::ASpawnHandler(const class FPostConstructInitializeProperties& PCIP)
    : Super(PCIP)
{
    SpawnLocation = { 0.0, 0.0, 1000.0 };
    SpawnRotation = { 0.0, 0.0, 0.0 };
    static ConstructorHelpers::FObjectFinder<UBlueprint> SpecifiedSpawnObject(TEXT("Blueprint'/Game/ThingToSpawn.ThingToSpawn'"));
    WhatToSpawn = (UClass*)SpecifiedSpawnObject.Object->GeneratedClass;
}

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

    if (WhatToSpawn != NULL)
    {
        UWorld* const World = GetWorld();
        if (World)
        {
            FActorSpawnParameters SpawnParams;
            SpawnParams.Owner = this;
            SpawnParams.Instigator = Instigator;
            SpawnParams.bNoCollisionFail = true;
            AActor* const SpawningObject = World->SpawnActor<AActor>(WhatToSpawn, SpawnLocation, SpawnRotation, SpawnParams);
        }
    }
}


Thanks a lot for the explanation Lauren, finally got it working and understand it a great deal better now!