Casting TSubclassOf BP actor to base class

I’m trying to equip an enemy character with a blueprint weapon derived from base weapon c++ class.

header:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Guns, meta=(AllowPrivateAccess = "true"))
	TSubclassOf<AMyWeaponBase> EnemyWeapon;

constructor or BeginPlay():

// Equip Weapon
	const USkeletalMeshSocket* WeaponSocket = GetMesh()->GetSocketByName("WeaponSocket");
	if (WeaponSocket && EnemyWeapon)
	{
		AMyWeaponBase* Weapon = Cast<AMyWeaponBase>(EnemyWeapon);
		if (Weapon)
		{
			Weapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetIncludingScale, "WeaponSocket");
			Weapon->WeaponMesh->SetCollisionResponseToChannel(ECC_Pawn, ECR_Ignore);
			Weapon->bRotate = false;
		}		
	}

Since I couldn’t call AttachToComponent() from EnemyWeapon directly I tried casting it to base, it compiled but didn’t work in game. Since same attachment code already works in my player character class I’m thinking the casting doesn’t work somehow.

TSubclassOf holds a class not an instance of an actor.

You’ll need to spawn an instance first using the subclass. Something like

AMyWeaponBase* Weapon = Cast<AMyWeaponBase>(GetWorld()->SpawnActor(EnemyWeapon, ...))

Yeah I figured I might need to do that after searching for a solution but couldn’t make it work, should’ve added it to question:

FActorSpawnParameters SpawnParams;
		AMyWeaponBase* Weapon = Cast<AMyWeaponBase>(GetWorld()->SpawnActor(EnemyWeapon, GetActorLocation(), GetActorRotation(), SpawnParams); 

IDE underlines it red.

What error do you get if you compile it?

[C2664] ‘AActor *UWorld::SpawnActor(UClass *,const FTransform *,const FActorSpawnParameters &)’: cannot convert argument 2 from ‘FVector’ to ‘const FVector *’

Oh yeah my bad, & or maybe the local variables const will work. What’s going wrong with the attachment?

Sounds like a fun weapon stealing mechanic!

Try this:

FActorSpawnParameters SpawnParams;
FVector Location = GetActorLocation();
FRotator Rotation = GetActorRotation();
         AMyWeaponBase* Weapon = Cast<AMyWeaponBase>(GetWorld()->SpawnActor(EnemyWeapon, Location, Rotation, SpawnParams);

Same error.

Using “&” before Location and Rotation makes it compile without error for some reason but attachment doesn’t work in the game. Back to square one.

So this is the right way to do it?

    AMyWeaponBase* Weapon = Cast<AMyWeaponBase>(GetWorld()->SpawnActor(EnemyWeapon, &Location, &Rotation, SpawnParams));

For the attachment, self explanatory: weapon should be attached to enemy character’s WeaponSlot, it isn’t.

Now I noticed attachment is working but weapon gets attached to my player character instead of the enemy character when I move player character next to the enemy. And the reason should be the OnOverlapBegin() function in base weapon class which equips the weapon to player character. Guess I need to disable it for the enemy character somehow.

:slight_smile:

Now I think about it, this doesn’t prove the attachment code on enemy character is working, if anything it isn’t working since weapon just spawns albeit invisible on the enemy and only gets attached to player character’s skeletal mesh socket if player character overlaps with it.

Fixed it by changing the root component from CollisionVolume(that overlap functions are attached to) to WeaponMesh in base weapon class and destroying the CollisionVolume in enemy class after spawning the weapon.

Thanks for the help.