At first glance, I can’t see where your structure is failing. It looks pretty reasonable. Your blueprint loading looks correct, but you may be able to set up your weapons without having to use the ConstructorHelpers to grab a blueprint explicitly. Generally, I try to avoid doing that, since it limits your ability to reorganize your blueprint classes later on. Here’s an example of using TSubclassOf pointers to allow your users to select their weapon blueprints from the pawn blueprints’ defaults:
In the Pawn’s header, we set up two members: an array of weapon classes to spawn and an array of spawned weapon instances.
/** This pawn's weapon classes */
TArray<TSubclassOf<class AWarmachineWeapon> > Weapons;
/** This pawn's weapons. */
TArray<class AWarmachineWeapon*> WeaponInstances;
In our case, we handled our inventory in a component. Generally, I’d just recommend doing it in the pawn. From our component’s InitizlizeComponent(), we made a call to spawn the inventory:
AWarmachinePawn* OwnerWMPawn = Cast<AWarmachinePawn>(GetOwner());
// spawn weapons
for (int32 WeaponIdx = 0; WeaponIdx < Weapons.Num(); WeaponIdx++)
SpawnInfo.bNoCollisionFail = true;
class AWarmachineWeapon* NewWeapon = GetWorld()->SpawnActor<AWarmachineWeapon>(Weapons[WeaponIdx], SpawnInfo);
// Equip the first weapon by default.
The weapon’s OnEnterInventory() looks like this:
void AWarmachineWeapon::OnEnterInventory(AWarmachinePawn* NewOwner)
if (Role == ROLE_Authority)
Instigator = NewOwner;
MyPawn = NewOwner;
// net owner for RPC calls
// warmachine weapons are always visibly attached to their pawns, either in a holstered or an equipped position.
Your attachment method looks right to me. For reference, here’s what ours looks like (in our case, our weapons each store the socket names on their owning pawns to which they should be attached when equipped, and when holstered).
(WeaponMeshComponentName is just a static const FName we’re declaring in the class implementation:
static const FName WeaponMeshComponentName = FName(TEXT(“WeaponMesh”));
USceneComponent* DefaultWeaponMeshComponent = Cast<USceneComponent>(GetClass()->GetDefaultSubobjectByName(WarmachineWeaponConstants::WeaponMeshComponentName));
Mesh->RelativeLocation = DefaultWeaponMeshComponent->RelativeLocation;
Mesh->RelativeRotation = DefaultWeaponMeshComponent->RelativeRotation;
Mesh->RelativeScale3D = DefaultWeaponMeshComponent->RelativeScale3D;
AttachPoint = EquippedAttachPoint;
AttachPoint = HolsteredAttachPoint;
CurrentAttachPoint = AttachPoint;
Sorry I wasn’t able to spot exactly where your setup was failing, but maybe something in the examples I’ve provided will help.