0
\$\begingroup\$

I am trying to restart my shooting arrow if the arrow hits the roof but the bool is not changing [and giving a] cast failed [error] this is my shooter character shooting arrow

 void AShooterCharacter::BeginPlay()
{
   Super::BeginPlay();
   
}

// Called every frame
void AShooterCharacter::Tick(float DeltaTime)
{
   Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void AShooterCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
   Super::SetupPlayerInputComponent(PlayerInputComponent);

   PlayerInputComponent->BindAxis("MoveRight", this, &AShooterCharacter::MoveRight);
   PlayerInputComponent->BindAction("Shoot", IE_Pressed, this, &AShooterCharacter::Shoot);
   
}
void AShooterCharacter::MoveRight(float value)
{
   AddMovementInput(FVector(0.f, -1.0f, 0.f), value);

}
void AShooterCharacter::Shoot()
{
   UWorld* const world = GetWorld();
   if (world != nullptr)
   {
       if (bCanIShoot)
       {
           FVector location = GetActorLocation();
           world->SpawnActor<AArrow_Weapon>(Arrow, location, FRotator::ZeroRotator);
           ;
           bCanIShoot = false;
       }
       
   }
}

this is my arrow actor

{
    // 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;
    box = CreateDefaultSubobject<UBoxComponent>(TEXT("Box"));

}

// Called when the game starts or when spawned
void AArrow_Weapon::BeginPlay()
{
    Super::BeginPlay();
    box->OnComponentBeginOverlap.AddDynamic(this, &AArrow_Weapon::OvarlabBegin);
}

// Called every frame
void AArrow_Weapon::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    FVector newLocation = GetActorLocation();
    newLocation.Z += Speed * DeltaTime;
    SetActorLocation(newLocation);
}



void AArrow_Weapon::DesctroyArrow()
{
    Destroy();
}
void AArrow_Weapon::OvarlabBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
    if (OtherActor != nullptr)
    {
        if (OtherActor->ActorHasTag("TopRoof"))
        {
            iAShooterCharacter* player = Cast<AShooterCharacter>(OtherActor);

            if (player)
            {
                player->bCanIShoot = true;;
            }
            UE_LOG(LogTemp, Warning, TEXT("arrowHit11111"));

        }
    }
}
  
\$\endgroup\$
0
0
\$\begingroup\$

I think you said you are getting a failed cast error. This is because you are trying to cast the OtherActor to a AShooterCharacter. The OtherActor however is not the player, it is the roof. This is ensured by the ActorHasTag("TopRoof"). So you should remove the line setting player to a casted OtherActor.

You can't get the player that shot the arrow from the ceiling it hits. Instead, you should have the player that shot the arrow as a field in the AArrow_Weapon. When you spawn it you should pass in this(the player) to the constructor.

Then you can just set player->bCanIShoot.

Edit: Okay, so it looks like there's not a way to directly pass another parameter through the constructor. So instead, we'll set it right after it is spawned.

On the arrow class, add a field like AShooterCharacter* ShotBy. Then have a setter like

AArrow_Weapon::SetShotBy(AShooterCharacter* ShotBy){
    this->ShotBy = ShotBy;
}

Keep constructing it like you were before, but keep the pointer returned by SpawnActor. Use it to set the value.

AArrow_Weapon* justShot = SpawnActor<AArrow_Weapon>(Arrow, location, FRotator::ZeroRotator);
justShot->SetShotBy(this);
\$\endgroup\$
13
  • \$\begingroup\$ FActorSpawnParameters spawnparams; spawnparams.Owner = this; world->SpawnActor<AArrow_Weapon>(Arrow, location, FRotator::ZeroRotator,spawnparams); \$\endgroup\$
    – Sakur7
    Oct 6 '21 at 0:21
  • \$\begingroup\$ @Sakur7 what do you mean by that? Doesn't that error because it is not a valid overload? Did you try what I said? \$\endgroup\$ Oct 6 '21 at 0:31
  • 2
    \$\begingroup\$ @Sakur7 If you have more information you can edit your question. That way future readers with a similar problem can get info. You say "same error" but you have not put that error in the question at all so nobody knows what it is. \$\endgroup\$ Oct 6 '21 at 0:48
  • 1
    \$\begingroup\$ @Sakur7 There's really no reason to go on discord. Anything you say should be recorded here. It's very easy. You just click edit on your question and you can put new stuff in. \$\endgroup\$ Oct 6 '21 at 0:55
  • 1
    \$\begingroup\$ @Sakur7 You can put a screenshot in the post, but most likely it would be better in text. This site works based on the idea of Q and A. It builds a knowledge repository. If you can't describe your problem in a question, it's not a good fit for this site. \$\endgroup\$ Oct 6 '21 at 1:01
0
\$\begingroup\$
FActorSpawnParameters Params;
Params.Owner = this;
world->SpawnActor<AArrow_Weapon>(Arrow, location, FRotator::ZeroRotator,Params);

Then

if (OtherActor->ActorHasTag("TopRoof"))
{
   AShooterCharacter* player = Cast<AShooterCharacter>(GetOwner());
   
\$\endgroup\$
1
  • 3
    \$\begingroup\$ If this solved your problem, please edit your answer to explain in detail how this resolves the issue. If this is not a solution, you might have meant to post it as an edit to your question instead. \$\endgroup\$
    – DMGregory
    Oct 6 '21 at 14:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .