I see the dilemma, you have no location because you don’t specify the location on its SpawnActor. Possibly you spawn it at 0,0,0 then immediately attach it to the Players Grenade socket. Given that, you can continue to do that by using 0,0,0 in the FTransform(FVector(0.f,0.f,0.f)) so the FinishSpawning would look like
MyNewGrenade->SpawnActor(…);
MyNewGrenade->AmmoCount=MyRealAmmoCount;
MyNewGrenade->FinishSpawning(FTransform(FVector(0.f,0.f,0.f)));
… attach MyNewGrenade to grenade socket here …
Normally you would have a location that you are spawning something and specify it on the SpawnActor statement. I didn’t realize that you didn’t but were spawning with a default location and then immediately attaching it.
Here is an example of how I use deferred spawning (I have a macro that does the SpawnActor so SpawnBPDeferred is just a macro that sets the spawn params and launches the spawn). In this I spawn, set lots of parameters and even call a function within the not-yet-spawned Weapon to do some initialization. Then I complete the spawn with FinishSpawning. Until that FinishSpawning statement, the weapon doesn’t exist in the world, but I can manipulate stuff within it.
AUsableItem* AMyCharacter::SpawnWeapon(int32 wi,FVector SpawnAtLoc) {
AUsableItem* TempWeapon = SpawnBPDeferred(GetWorld(), GI->TheLS->WeaponInventory[wi].WeaponObject, SpawnAtLoc, FRotator(0.0f,0.0f,0.0f));
AWeapon* NewWeapon = Cast(TempWeapon);
NewWeapon->WeaponExisted=true; //probably coming out of inventory and was initialized with unique stuff prior to this
NewWeapon->Description=GI->TheLS->WeaponInventory[wi].WeaponDescription;
NewWeapon->Barrel=GI->TheLS->WeaponInventory[wi].Barrel;
NewWeapon->Stock=GI->TheLS->WeaponInventory[wi].Stock;
NewWeapon->Clip=GI->TheLS->WeaponInventory[wi].Clip;
NewWeapon->Scope=GI->TheLS->WeaponInventory[wi].Scope;
NewWeapon->BaseUniqueID=GI->TheLS->WeaponInventory[wi].BaseUniqueID;
NewWeapon->Favorite=GI->TheLS->WeaponInventory[wi].Favorite;
UE_LOG(LogTemp,Warning,TEXT(“LS GetNextWeapon: We selected %s as next weapon with base id as %s”),*NewWeapon->Description,*NewWeapon->BaseUniqueID);
NewWeapon->WeaponDetail=GI->TheLS->WeaponInventory[wi].WeaponDetail;
NewWeapon->AlternateFireDetail=GI->TheLS->WeaponInventory[wi].AlternateFireDetail;
// BARREL
if(NewWeapon->Barrel != nullptr) NewWeapon->PreloadValues1=GI->TheLS->WeaponInventory[wi].AttachmentDetail1;
// STOCK
if(NewWeapon->Stock != nullptr) NewWeapon->PreloadValues2=GI->TheLS->WeaponInventory[wi].AttachmentDetail2;
// CLIP
if(NewWeapon->Clip != nullptr) NewWeapon->PreloadValues3=GI->TheLS->WeaponInventory[wi].AttachmentDetail3;
// SCOPE
if(NewWeapon->Scope) NewWeapon->PreloadValues4=GI->TheLS->WeaponInventory[wi].AttachmentDetail4;
NewWeapon->PreProcessSetup();
//we are using a default transform because this weapon will be placed in the characters hands after this
NewWeapon->FinishSpawning(FTransform(FVector(SpawnAtLoc)));
GI->TheLS->PlayerSettings.BaseUniqueID=NewWeapon->BaseUniqueID;
return TempWeapon;
}
I just realized something that may be confusing. Just ignore the NewWeapon vs TempWeapon. It is just that our Weapons are a separate subclass for inventory, sales and pickup purposes called AUsableItem but then have to be referred to as the subclass AWeapon for access to the real detail weapon parameters. Not important.