Adding Player Velocity to Grenade Toss

I’ve been able to create a simple grenade toss that inherits the velocity of its throwing pawn with the following simple code:



void AShooterThrown::InitVelocity(FVector& ShootDirection)
{
	if (GetInstigatorController())
	{
		APawn * Pawn = GetInstigatorController()->GetPawn();
		if (Pawn)
		{
			FVector PawnVelocity = Pawn->GetVelocity();
			FVector Impulse = (ShootDirection * 2000.0f) + PawnVelocity;
			ThrownMesh->AddImpulse(Impulse);

			UE_LOG(LogTemp, Warning, TEXT("PawnVelocity: %s"),*PawnVelocity.ToString());
			UE_LOG(LogTemp, Warning, TEXT("ShootDirection: %s"), *ShootDirection.ToString());
			UE_LOG(LogTemp, Warning, TEXT("Impulse: %s"), *Impulse.ToString());
			/*
			LogTemp:Warning: PawnVelocity: X=439.999 Y=-0.734 Z=0.000
			LogTemp:Warning: ShootDirection: X=0.836 Y=-0.001 Z=0.548
			LogTemp:Warning: Impulse: X=2112.495 Y=-3.190 Z=1096.700
			*/
		}
	}
}


In practice though I’ve found that the left/right strafing of the player that the grenade inherits is not ideal.

I would like to only apply the forward/backward velocity of the player to the grenade and ignore the side-to-side component.

My naive attempt: FVector Impulse = (ShootDirection * 2000.0f) + (PawnVelocity * ShootDirection);
Has the weird side effect of being relative to the world and not the player. So if the player is running North it will always add velocity to the grenade, if the player is running south it will remove velocity.

What am I not understanding?

On my mobile, so cannot test, but had a thought. My guess is maybe (ShootDirection * 2000.0f) + (ShootDirection.normalize * PawnVelocity.size) could do it. To eliminate backwards movement from reducing velocity, maybe an if statement that checks for negative shoot * pawn results then assigns 0. Maybe a dot product check would be better.

Probably a more elegant way about it, but figured to give it a stab.

Edit: NM, the size probably adds magnitude without regard to which way the character moves. No negative results. So, just need to do a check for backwards move and make sure it doesn’t add any additional velocity.

Tim thanks for the suggestion but I think you may have misunderstood me.

I do want to add negative velocity to the grenade if the player is running backwards and in fact: FVector Impulse = (ShootDirection * 2000.0f) + PawnVelocity; accomplishes that.

But what is weird is when I try to remove the strafing by doing: FVector Impulse = (ShootDirection * 2000.0f) + (PawnVelocity * ShootDirection); then if I run forwards North the grenade gets positive velocity but if I run forwards South (I’m running forwards South not backwards) the grenade gets negative velocity. So I think something about my second approach does not take local/global space into account?

This will add the velocity when you’re travelling in the direction you’re throwing. If you’re throwing straight up while walking around, it won’t add velocity because you’re not technically travelling in the up direction unless you jump and throw. If you want it to behave differently, like adding the pawns forward velocity even when you’re aiming up then set ForwardDirection to whatever you consider to be the players ‘forward’ direction (this could be the controllers forward vector, and/or the pawns forward vector, depending on how you set up your game).



//will only impart velocity along this axis, it could be the direction you're throwing, or the direction the player is facing, either way it needs to be a unit vector
FVector ForwardDirection = ShootDirection;
FVector Impulse = ShootDirection * 2000.f + ForwardDirection * FVector::DotProduct(ForwardDirection ,PawnVelocity); 


Hey thanks a lot for that, the grenade toss ignores the side to side motion of the player now but keeps their forward/backward velocity. I tried using the pawn’s forward direction but it did not transfer the player’s upward velocity if they tried to jump throw a grenade so I’ll stick with using their ShootDirection.