I have a class Item_Base, and it has a derived class Item_Weapon. I’ve got multiple Item_Weapon blueprints made with different stats and such.
I want to spawn my character with one of those weapon blueprints already equipped, so I figured the way to do so would be to get a reference to the Blueprint in code, then I would set it as the equipped weapon on BeginPlay.
Here’s what I’m doing in the constructor:
ConstructorHelpers::FObjectFinder<UBlueprint> weaponBP(TEXT("Blueprint'/Game/Blueprints/Items/Weapon_Unarmed.Weapon_Unarmed'"));
if (weaponBP.Succeeded())
{
spawnWeapon = Cast<AItem_Weapon>(weaponBP.Object);
}
I was able to get this far by searching the forums, but I can’t determine why the cast is failing every time.
In the header spawnWeapon is declared as a pointer:
The FObjectFinder found an asset of blueprint and not a real actor in the world. You need to spawn real actor of the weapon based on this blueprint and use it. In short, weaponBP.Object has type UBlueprint not an AActor, you can’t cast these types.
I actually kept reading on this for a while after making the post, and I found out essentially what you wrote… it’s finding a reference to the blueprint itself, but I was not creating a real instance of it in the world.
But I wasn’t able to find the code to properly do that yet. Do you have any tips to point me in the right direction?
I think UWorld::SpawnActor and UBlueprint::GetBlueprintClass is right direction. But in some cases you should compile blueprints before you can use it.
Do you know where I can find an example of this to base my code from, or is it the kind of thing that people don’t do often and I’ll need to experiment until it works?
I solved it so I wanted to post my solution. I am using UE 4.23, by the way. Most of the documentation I found pertaining to this was for much older versions, but at least now I have confirmed this method works just fine.
ConstructorHelpers::FObjectFinder<UBlueprint> weaponBP(TEXT("Blueprint'/Game/Blueprints/Items/Weapon_Unarmed.Weapon_Unarmed'"));
if (weaponBP.Object)
{
spawnWeapon = (UClass*)weaponBP.Object->GeneratedClass;
}
And then, in BeginPlay():
UWorld* const world = GetWorld();
if (world)
{
AItem_Weapon* equipOnSpawn = world->SpawnActor<AItem_Weapon>(spawnWeapon);
if (equipOnSpawn)
{
SetEquippedWeapon(Cast<AItem_Weapon>(equipOnSpawn));
}
}
Not really a fan of the fact that I had to use two variables to get it in BeginPlay(), but I suppose it’s unavoidable due to ConstructorHelpers being just that, only for the constructor. The big part I was missing was that I wasn’t actually creating an instance of the BP at all, so SpawnActor() corrected that. Running this code successfully started my character off with the unarmed “weapon” I had created.