x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

UGameplayStatics::ApplyRadialDamage

Hello. Im trying to apply radial damage but its no doing any damage. Everything working in the function in which im using radial damage. Just so you know, i do have take any damage in my player class and point damage is already working but now i've included radial damage and its not working(no damage).

I tried exact same thing that you suggested and still nothing no UE_LOG. So here is what exactly im doing. I have an actor component which im using as a health cmoponent. This is the actor component code:

 USHealthComponent::USHealthComponent()
 {
     // Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
     // off to improve performance if you don't need them.
     PrimaryComponentTick.bCanEverTick = true;
 
     DefaultHealth = 100;
     SetIsReplicated(true);
 }
 
 
 // Called when the game starts
 void USHealthComponent::BeginPlay()
 {
     Super::BeginPlay();
 
     if (GetOwnerRole() == ROLE_Authority)
     {
         AActor* MyOwner = GetOwner();
         if (MyOwner)
         {
             MyOwner->OnTakeAnyDamage.AddDynamic(this, &USHealthComponent::HandleTakeAnyDamage);
         }
     }
     
     Health = DefaultHealth;
 }
 
 void USHealthComponent::HandleTakeAnyDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser)
 {
     if (Damage <= 0.0f)
     {
         return;
     }
     Health = FMath::Clamp(Health - Damage, 0.0f, DefaultHealth);
     UE_LOG(LogTemp, Warning, TEXT("Health is %s"), *FString::SanitizeFloat(Health))
 
     OnHealthChanged.Broadcast(this, Health, Damage, DamageType, InstigatedBy, DamageCauser);
 }

As you can see i also also have DECLARE_DYNAMIC_MULTICAST_DELEGATE in actor component which has 2 additional parameters. Now in my Player class im binding that broadcast in BeginPlay(). Here is the player class code of bind function:

 void ASCharacter::OnHealthChanged(USHealthComponent* OwningHealthComp, float Health, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser)
 {
     if (Health <= 0.0f && !bDied)
     {
         bDied = true;
         GetMovementComponent()->StopMovementImmediately();
         GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
 
         DetachFromControllerPendingDestroy();
 
         SetLifeSpan(10.0f);
     }
 }

This is the code im using and point damage does work with this but not radial. As i mentioned in the start, i tried adding OnTakeRadialDamage in Player class separately but still not receiving.

Product Version: UE 4.21
Tags:
more ▼

asked Mar 16 '19 at 08:35 PM in C++ Programming

avatar image

GameGod786
3 1 2

avatar image Elou44 Mar 17 '19 at 08:11 PM

Hi GameGod786, I have updated my answer with a minimal demo.

(comments are locked)
10|2000 characters needed characters left

2 answers: sort voted first

Hi GameGod786,

[UPDATE - 17/03/19]

Here is a minimal demo of what you're trying to achieve. I have created two classes:

  • ARadialDamageActor : The actor that 'explodes' and deals radial damages.

  • ADamageableActor : The actor that receives the damage.

RadialDamageActor.h

   UCLASS()
 class MYPROJECTCPP_API ARadialDamageActor : public AActor
 {
     GENERATED_BODY()
     
 public:    
     // Sets default values for this actor's properties
     ARadialDamageActor(const FObjectInitializer& ObjectInitializer);
 
 protected:
     // Called when the game starts or when spawned
     virtual void BeginPlay() override;
 
     UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
     class UStaticMeshComponent * StaticMeshComponent;
 
 public:    
     void Explode();
     
 };

RadialDamageActor.cpp

 // Sets default values
 ARadialDamageActor::ARadialDamageActor(const FObjectInitializer& ObjectInitializer)
     : Super(ObjectInitializer)
 {
      // 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;
 
     StaticMeshComponent = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Static Mesh Component"));
     RootComponent = StaticMeshComponent;
 }
 
 // Called when the game starts or when spawned
 void ARadialDamageActor::BeginPlay()
 {
     Super::BeginPlay();
     
     Explode();
 }
 
 void ARadialDamageActor::Explode()
 {
     UE_LOG(LogTemp, Warning, TEXT("ARadialDamageActor::Explode"));
 
     TArray<AActor*> IgnoredActors;
 
     UGameplayStatics::ApplyRadialDamage(this, 50.0f, GetActorLocation(), 500.0f, nullptr, IgnoredActors, this, GetInstigatorController(), true);
 }

DamageableActor.h

 UCLASS()
 class MYPROJECTCPP_API ADamageableActor : public AActor
 {
     GENERATED_BODY()
     
 public:    
     // Sets default values for this actor's properties
     ADamageableActor(const FObjectInitializer& ObjectInitializer);
 
 protected:
 
     UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
     class UStaticMeshComponent * StaticMeshComponent;
 
     UFUNCTION()
     void TakeAnyDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, class AController* InstigatedBy, AActor* DamageCauser);
 
     UFUNCTION()
     void TakeRadialDamage(AActor* DamagedActor, float Damage, const class UDamageType* DamageType, FVector Origin, FHitResult HitInfo, class AController* InstigatedBy, AActor* DamageCauser);
 };


DamageableActor.cpp

 // Sets default values
 ADamageableActor::ADamageableActor(const FObjectInitializer& ObjectInitializer)
     : Super(ObjectInitializer)
 {
      // 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;
 
     StaticMeshComponent = ObjectInitializer.CreateDefaultSubobject<UStaticMeshComponent>(this, TEXT("Static Mesh Component"));
     RootComponent = StaticMeshComponent;
 
     // Bind functions to OnTakeAnyDamage and OnTakeRadialDamage delegates
     OnTakeAnyDamage.AddDynamic(this, &ADamageableActor::TakeAnyDamage);
     OnTakeRadialDamage.AddDynamic(this, &ADamageableActor::TakeRadialDamage);
 }
 
 void ADamageableActor::TakeAnyDamage(AActor * DamagedActor, float Damage, const UDamageType * DamageType, AController * InstigatedBy, AActor * DamageCauser)
 {
     UE_LOG(LogTemp, Warning, TEXT("ADamageableActor::TakeAnyDamage - %f"), Damage);
 }
 
 void ADamageableActor::TakeRadialDamage(AActor * DamagedActor, float Damage, const UDamageType * DamageType, FVector Origin, FHitResult HitInfo, AController * InstigatedBy, AActor * DamageCauser)
 {
     UE_LOG(LogTemp, Warning, TEXT("ADamageableActor::TakeRadialDamage - %f"), Damage);
 }

In my demo, when I press play, both 'TakeRadialDamage' and 'TakeRadialDamage' are being called once.

Please, tell me if that doesn't help.

Cheers.

more ▼

answered Mar 17 '19 at 02:13 AM

avatar image

Elou44
174 3 9 7

avatar image GameGod786 Mar 17 '19 at 01:57 PM

Thanks for reply. I mentioned above that i do have OnTakeAnyDamage on my player class. I also have weapon class and i have point damage using line trace on weapon and its working but then i made a bot which is suppose to explode when near the player. So in one function i have exploding code like particles sound etc and in there i also have ApplyRadialDamage. Everything in that function works except radial damage. Hope i explained everything.

avatar image Elou44 Mar 17 '19 at 02:32 PM

Hi, can you update your original post and show the part where you bind a function to the 'OnTakeAnyDamage' delegate as well as the function itself?

avatar image GameGod786 Mar 18 '19 at 12:14 PM

Hello. I tried moving HandleTakeAnyDamage in contructor as you suggested. I dont get any compile error but its like the function doesnt exist(Not called when hit). I also tried moving my bot's and player's bind function(OnHealthChanged) from beginplay to constructor, same thing happened, no error but function are not getting called(by the way im using UFUNCTION() on every bind function). In my code it seems like bind function only wanna work in beginplay and not in constructor.

avatar image Elou44 Mar 18 '19 at 12:46 PM

Two more things to check : are the exploding actor and the damageable actor close enough (with a distance < to the damage radius set in ApplyRadialDamage)? And is the collision response to the visibility channel of your damageable actor set to block? If that doesn’t help, I will need to see your project to further assist you.

avatar image GameGod786 Mar 18 '19 at 04:05 PM

Yes the distance is less then the radious because i tested it with DrawDebugSphere on bot's location. Player Capsule has everything set to block except visibility and camera. Player Mesh set to block all. Also there is one problem. Im telling because it might be connected to my damage problem. So im using a sphere component on my bot which triggers overlap event.

 SphereComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
     SphereComp->SetSphereRadius(200);
     SphereComp->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
     SphereComp->SetCollisionResponseToAllChannels(ECR_Ignore);
     SphereComp->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
     SphereComp->SetupAttachment(RootComponent);

Now the problem i was facing here is that the OnComponentBeginOverlap was not firing when it overlaps with the pawn but i clearly set it to do so. After messing around i found out that i have to set everything on sphereComp to ignore except worldstatic(Overlaps) which makes no sense to me because i think pawn should be the one overlaping not worldstatic. So i have no idea why worldstatic has to be the one overlaping.

(comments are locked)
10|2000 characters needed characters left

So OnTakeAnyDamage does not receive radial damage? Is this the reason i have to use both OnTakeAnyDamage and OnTakeRadialDamage? Because i thought i could just do it with only OnTakeAnyDamage.

more ▼

answered Mar 17 '19 at 09:19 PM

avatar image

GameGod786
3 1 2

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question