First, you need to set a way to change the value of the bHold variable. Either by the player clicking again causing
ABow_ArrowCharacter::Draw() to be called again, which sould be something like:
Then, on the tick function, you need to calculate the speed of the projectile based on how much time the key was held down. You should clamp the held time though because we dont want our arrows to be able to fly to the moon as soon as the player has charged enough.
Super::Tick(DeltaTime);
{
if (!bHold && ChargeTime!=0) //shoot the arrow
{
float ChargePercent = FMath::Clamp(ChargeTime, 0.0f, MaxChargeTime)/MaxChargeTime;
float Speed = ChargePercent*MaxArrowSpeed;
//spawn the projectile here, with the appropriate direction and speed
ChargeTime = 0;//reset the charge time timer
bHold = false;
}else{
ChargeTime+=DeltaTime;//keep adding charge time, the player does not want to shoot yet
}
}
Notice the 2 extra variables: MaxArrowSpeed and MaxChargeTime: Max Charge time is the max time the user can charge his bow in order to achieve a speed of MaxArrowSpeed (this is why we clamp).
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("Collision_comp"));
CollisionComp->InitSphereRadius(5.0f);
CollisionComp->BodyInstance.SetCollisionProfileName("Arrow");
//CollisionComp->BodyInstance.SetCollisionProfileName("Projectile");
CollisionComp->OnComponentHit.AddDynamic(this, &AProjectile_Arrow::OnHit);
RootComponent = CollisionComp;
ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
ProjectileMovement->UpdatedComponent = CollisionComp;
//ProjectileMovement->InitialSpeed = 2000.0f;
//ProjectileMovement->MaxSpeed = 2000.0f;
ProjectileMovement->bRotationFollowsVelocity = true;
ProjectileMovement->ProjectileGravityScale = 0.5f;
ProjectileMovement->bShouldBounce = false;
ArrowMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Arrow"));
ArrowMesh->AttachTo(RootComponent);
InitialLifeSpan = 3.0f;
}
Would be great If anyone can shed light on how I can get this done. Thanks a lot in advance.
Thanks a lot. It makes a lot more sense. But one small doubt, spawning a projectile in a tick will spam the arrows right?
and I have already got the arrows to travel in the direction I aim in the release function. So should I copy and paste it in the tick function?
I have been trying this out for the past two days and sorry but as i suspected before the arrows are being spammed not sure if I am doing something wrong.
Since you implemented a Release function, you could revert to having Draw just setting bHold to true. Then, move these parts to the functions accordingly:
this should solve all of your problems. You might also want to add a delay before the player is able to re-draw an arrow.
I have been trying to do this myself but seems like I am stuck big time. Sorry for being such a pain. I did what you told and the arrow spawns only for the first time and after that it never spawns. So i changed it like this