I know this question have been adressed decent amount of times, and I’ve read alot of solutions, but still struggle to understand what am I doing wrong, so please advice!
I have a c++ class “ADialogueCharacter : public ACharacter”, from this class I’ve created blueprint “NPC_generic” and every NPC derives from this blueprint, for example Hitch and Bill.
Now, on game start I’m loading NPC’s in MyGameMode.
ATheBarGameMode.cpp
ATheBarGameMode::ATheBarGameMode()
{
............................
NPC_forDay.Empty();
NPC_forDay.Add(UDayFlow::LoadNPCBlueprint(TEXT("Blueprint'/Game/NPC/Hitch.Hitch_C'"), 13));
NPC_forDay.Add(UDayFlow::LoadNPCBlueprint(TEXT("Blueprint'/Game/NPC/NPC_generic.NPC_generic_C'"), 0));
NPC_forDay.Add(UDayFlow::LoadNPCBlueprint(TEXT("Blueprint'/Game/NPC/Bill.Bill_C'"), 11));
.............................
}
The function I use to load them is a static library function, which takes NPC asset location and unique NPC ID
FNPC_BP UDayFlow::LoadNPCBlueprint(FString refPath, int char_ID)
{
ConstructorHelpers::FObjectFinder<UClass> NPC_BP(*refPath);
if (NPC_BP.Object)
{
FNPC_BP singleNPC;
singleNPC.BP_Ref = NPC_BP.Object;
singleNPC.NPC_ID = char_ID;
return singleNPC;
}
return FNPC_BP();
}
All the code above is sligtly modified, because before I used FObjectFinder and loaded blueprits, which worked in editor, but gave me errors with missing assets when i packaged a game. I found out, that I could not load BP’s outside editor, and it’s kind of a right thing, so after some ressearch switched to UClass.
This time packaged game started good, and there were no errors, but It turned out, that no NPC was spawning, despite the fact that all spawning code below seems to be working.
The spawning function itself I borrowd from Rama, here it is:
template <typename VictoryObjType>
static FORCEINLINE VictoryObjType* SpawnBP(
UWorld* TheWorld,
UClass* TheBP,
const FVector& Loc,
const FRotator& Rot,
const bool bNoCollisionFail = true,
AActor* Owner = NULL,
APawn* Instigator = NULL
) {
if(!TheWorld) return NULL;
if(!TheBP) return NULL;
FActorSpawnParameters SpawnInfo;
SpawnInfo.bNoCollisionFail = bNoCollisionFail;
SpawnInfo.Owner = Owner;
SpawnInfo.Instigator = Instigator;
SpawnInfo.bDeferConstruction = false;
return TheWorld->SpawnActor<VictoryObjType>(TheBP, Loc, Rot, SpawnInfo);
}
and I use it like that:
ACharacter* UDayFlow::executeEventSpawnNPC(
FEventCharComes charComesEvent,
TArray <FNPC_BP> NPC_BP_Ref,
UWorld* TheWorld,
const FVector& Loc,
const FRotator& Rot
) {
int char_ID = charComesEvent.char_ID;
FNPC_BP *NPC_BP = NPC_BP_Ref.FindByPredicate([char_ID](const FNPC_BP& item) {return item.NPC_ID == char_ID; });
if (NPC_BP != nullptr)
{
ACharacter* spawnedNPC = SpawnBP<ACharacter>(TheWorld, NPC_BP->BP_Ref, Loc, Rot);
return spawnedNPC;
};
return nullptr;
}
Here I find NPC reference, which I got from ObjectFinder in the first code fragment and try to spawn it as ACharacter type. I made absolutely no changes to this part of code, comparing to when I was loading BP’s directly and I don’t understand what could I change here.
Will appreciate any help.