Get access to current weapon

Hello everyone, help me implement tracing from the muzzle in file

LyraGameplayAbility_RangedWeapon.cpp
...
FTransform ULyraGameplayAbility_RangedWeapon::GetTargetingTransform(APawn* SourcePawn, ELyraAbilityTargetingSource Source) const
{
	check(SourcePawn);
	AController* SourcePawnController = SourcePawn->GetController(); 
	ULyraWeaponStateComponent* WeaponStateComponent = (SourcePawnController != nullptr) ? SourcePawnController->FindComponentByClass<ULyraWeaponStateComponent>() : nullptr;

	// The caller should determine the transform without calling this if the mode is custom!
	check(Source != ELyraAbilityTargetingSource::Custom);

	const FVector ActorLoc = SourcePawn->GetActorLocation();
	FQuat AimQuat = SourcePawn->GetActorQuat();
	AController* Controller = SourcePawn->Controller;
	FVector SourceLoc;

	double FocalDistance = 1024.0f;
	FVector FocalLoc;

	FVector CamLoc;
	FRotator CamRot;
	bool bFoundFocus = false;


	if ((Controller != nullptr) && ((Source == ELyraAbilityTargetingSource::CameraTowardsFocus) || (Source == ELyraAbilityTargetingSource::PawnTowardsFocus) || (Source == ELyraAbilityTargetingSource::WeaponTowardsFocus)))
	{
		// Get camera position for later
		bFoundFocus = true;

		APlayerController* PC = Cast<APlayerController>(Controller);
		if (PC != nullptr)
		{
			PC->GetPlayerViewPoint(/*out*/ CamLoc, /*out*/ CamRot);
		}
		else
		{
			SourceLoc = GetWeaponTargetingSourceLocation();
			CamLoc = SourceLoc;
			CamRot = Controller->GetControlRotation();
		}

		// Determine initial focal point to 
		FVector AimDir = CamRot.Vector().GetSafeNormal();
		FocalLoc = CamLoc + (AimDir * FocalDistance);

		// Move the start and focal point up in front of pawn
		if (PC)
		{
			const FVector WeaponLoc = GetWeaponTargetingSourceLocation();
			CamLoc = FocalLoc + (((WeaponLoc - FocalLoc) | AimDir) * AimDir);
			FocalLoc = CamLoc + (AimDir * FocalDistance);
		}
		//Move the start to be the HeadPosition of the AI
		else if (AAIController* AIController = Cast<AAIController>(Controller))
		{
			CamLoc = SourcePawn->GetActorLocation() + FVector(0, 0, SourcePawn->BaseEyeHeight);
		}

		if (Source == ELyraAbilityTargetingSource::CameraTowardsFocus)
		{
			// If we're camera -> focus then we're done
			return FTransform(CamRot, CamLoc);
		}
	}

	if ((Source == ELyraAbilityTargetingSource::WeaponForward) || (Source == ELyraAbilityTargetingSource::WeaponTowardsFocus))
	{
		SourceLoc = GetWeaponTargetingSourceLocation();
	}
	else
	{
		// Either we want the pawn's location, or we failed to find a camera
		SourceLoc = ActorLoc;
	}

	if (bFoundFocus && ((Source == ELyraAbilityTargetingSource::PawnTowardsFocus) || (Source == ELyraAbilityTargetingSource::WeaponTowardsFocus)))
	{
		// Return a rotator pointing at the focal point from the source
		return FTransform((FocalLoc - SourceLoc).Rotation(), SourceLoc);
	}

	// If we got here, either we don't have a camera or we don't want to use it, either way go forward
	return FTransform(AimQuat, SourceLoc);
}
...

All if’s start method GetWeaponTargetingSourceLocation()

FVector ULyraGameplayAbility_RangedWeapon::GetWeaponTargetingSourceLocation() const
{
	// Use Pawn's location as a base
	APawn* const AvatarPawn = Cast<APawn>(GetAvatarActorFromActorInfo());
	check(AvatarPawn);

	const FVector SourceLoc = AvatarPawn->GetActorLocation();
	const FQuat SourceRot = AvatarPawn->GetActorQuat();

	FVector TargetingSourceLocation = SourceLoc;

	//@TODO: Add an offset from the weapon instance and adjust based on pawn crouch/aiming/etc...

	return TargetingSourceLocation;
}

It contains GetActorLocation() and GetActorQuat() from AvatarPawn.
How to get the socket of the current weapon and its position and rotation?

Hi Muskatin, did you found out how to get it? i have now the same kind of Challenge. I need to get the Muzzle Socket from Current Weapon as Source and Muzzle Forward Vector as Target.
I did the muzzle in BluePrints but how to do in C++ :slight_smile:

Kind regards,
Ivan

This code is still in the “to do list” of devs.

The quickest way I’ve found in blueprints was:
get the character → get all attached actors (Weapon and Character Parts) → for each loop → cast to B_Weapon. From there, you can Get Skeletal Mesh and Get Socket Location. Now you need to find someone to help you convert this code into C++. Have you reached the developers in the Lyra Discord? Lyra Dev Net

In Lyra, the “official” way to get the current weapon is done via a Macro “Lyra Get Weapon”:
image

Which translates to a long code that uses a custom function “Get Spawned Actors”:

Again, you’ll need someone good with C++ to help you translating this macro into c++.

1 Like

I studied some C++ :smiley: and with the Following Lines i could retrieve the current Equiped Weapon in c++:
i used it in LyraGameplayAbility_RangedWeapon.cpp

within the following function:

FTransform ULyraGameplayAbility_RangedWeapon::GetTargetingTransform(APawn* SourcePawn, ELyraAbilityTargetingSource Source) const

if (Source == ELyraAbilityTargetingSource::Custom) {


ULyraEquipmentInstance* LEI_SR = GetAssociatedEquipment();
TArray<AActor*> SpawnedActorsSR = LEI_SR->GetSpawnedActors();
AActor* SpawnedActor_SR = SpawnedActorsSR[0]; //B_ColtPistol_SR_C_0
USkeletalMeshComponent* WeaponMeshSR = SpawnedActor_SR->GetComponentByClass();

// We already have Weapon Socket Location and Rotation (Quat) separately → No need for >SocketTransform
//FTransform WeaponMeshTransformSR = WeaponMeshSR->GetSocketTransform(SocketNameSR);
FVector WeaponSocketLocationSR = WeaponMeshSR->GetSocketLocation(SocketNameSR);
FRotator WeaponSocketRotationSR = WeaponMeshSR->GetSocketRotation(SocketNameSR);
FQuat WeaponSocketRotationQuatSR = WeaponMeshSR->GetSocketRotation(SocketNameSR).Quaternion();

//SR SourceLocation, AimQuat
//Original – SourceLoc = GetWeaponTargetingSourceLocation();
SourceLoc = WeaponSocketLocationSR;
AimQuat = WeaponSocketRotationQuatSR;

The Current Weapon is always the first index in Array (0).

Not sure if i should include UPROPERTY() so the Pointer doesnt get Garbage Collected or is it here not necessary?
Because i have observed, that after every Weapon Equip / unequip the SpawnActor gets incremented, B_ColtPistol_SR_C_0 → B_ColtPistol_SR_C_1 ->B_ColtPistol_SR_C_2 and so on. Not sure if this is normal behaviour. What i know is that Lyra destroys the actor after unequip and spawns it completely new after equip, but keeps all the “old” references. Is there a need to destroy them or Garbage Collect them manually or something like that or is this normal behaviour and UE manages it under the hud? I think at somepoint the increment will reach its limit. This behaviour is also here when player gets killed and respawned. B_Hero_Mannequin_SR_C_0 → B_Hero_Mannequin_SR_C_1 → B_Hero_Mannequin_SR_C_2.

Kind regards,
Ivan

1 Like