Hello,
First of i would like to warn people i started using unreal since 2 months and never programmed c++ before so if i do something stupid i would appreciate some feedback
So in our team we had some trouble figuring out a way to actually spawn a blueprint actor (or anything else for that matter) from c++ and then to do it in a efficient way.
An example of getting a blueprint class in code:
ConstructorHelpers::FClassFinder<AGun> BPClass(TEXT("/Game/Path/To/My/Gun/Bluepr"));
And then spawning it
GunInstance = world->SpawnActor<AGun>(BPClass.Class, spawnParams);
But the only way we found to get the blueprint classes in code was with the ContructorHelpers::FClassFinder which only work in the Constructor (surprise :p).
So i found a few examples which add a TSubclassOf BPClass; variable to their class so they can fill it in the constructor and use the class variable when something needs to be spawned outside of the constructor (bullets for example).
But in our case (to name 1 example where this gets ugly) is that we needed to have spawnpoints that randomly choice between all of our monsters. Which would have mend adding a variable of every monster blueprint in our game.
So because we didnāt feel like adding variables for every blueprint to all the classes that might need it (which would be quit some) we decided to use a single class (In our case a singleton) to handle all blueprint loading.
Below the .h file
#pragma once
/**
*
*/
class MOONSHINEWORKS_API BlueprintLoader
{
private:
//static BlueprintLoader* Instance;
BlueprintLoader();
~BlueprintLoader();
BlueprintLoader(BlueprintLoader const&); // Don't Implement
void operator=(BlueprintLoader const&); // Don't implement
TMap<FName, TSubclassOf<class UObject>> Classes;
public:
//void Initialize(const class FPostConstructInitializeProperties& PCIP);
static BlueprintLoader& Get(){
static BlueprintLoader Instance;
return Instance;
};
void AddBP(FName Name, TCHAR* Path);
TSubclassOf<class UObject> GetBP(FName Name);
};
And the .cpp file
#include "MOOnshineWorks.h"
#include "BlueprintLoader.h"
BlueprintLoader::BlueprintLoader()
{
AddBP(FName("BP_1"), TEXT("/Game/Path/To/My/Gun/Bluepr"));
AddBP(FName("BP_2"), TEXT("/Game/Path/To/My/Gun/Bluepr2"));
AddBP(FName("AndMyLastBluePrint"), TEXT("/Game/Path/To/My/Last/BlBlueprintuepr2"));
}
BlueprintLoader::~BlueprintLoader()
{
}
void BlueprintLoader::AddBP(FName Name, TCHAR* Path)
{
ConstructorHelpers::FClassFinder<UObject> BP(Path);
Classes.Add(Name, BP.Class);
}
TSubclassOf<class UObject> BlueprintLoader::GetBP(FName Name)
{
TSubclassOf<class UObject> Result = (*Classes.Find(Name));
if (Result){
return Result;
}
else{
return nullptr;
}
}
Then when we need to spawn a Blueprint
GunInstance = GetWorld()->SpawnActor<AGun>(TSubclassOf<AGun>(*(BlueprintLoader::Get().GetBP(FName("BP_2")))), spawnParams);
We currently add all classes needed in the constructor but somewhere down the line we will do something like parsing the content tree to include all blueprints (or something similar).
Or we could add a way to add Blueprint classes to the Classes array directly and add the blueprints in the classes we need them in.
Any thoughts on this way of spawning blueprints? Feedback in general is also greatly appreciated as always :D.
(I also quietly hope i saved someone some trouble by posting this :3)