"Onhit" function not working correctly

I am new to unreal and doing the tutorial from this video here:

The “Onhit” function the projectile class is not doing what its supposed to do.

Here is the projectile.h file:

        #pragma once

   #include "CoreMinimal.h"
   #include "GameFramework/Actor.h"
     #include "FPSProjectile.generated.h"


     class UProjectileMovementComponent;
      class USphereComponent;


     UCLASS()
      class AFPSProjectile : public AActor
      {
GENERATED_BODY()

      protected:

      /** Sphere collision component */
        UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category= "Projectile")
            	USphereComponent* CollisionComp;

   /** Projectile movement component */
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Movement")
    UProjectileMovementComponent* ProjectileMovement;

      public:

  AFPSProjectile();

   /** called when projectile hits something */
     UFUNCTION(BlueprintCallable)
	virtual void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* 
      OtherComp, FVector NormalImpulse, const FHitResult& Hit);

     /** Returns CollisionComp subobject **/
      USphereComponent* GetCollisionComp() const { return CollisionComp; }

   /** Returns ProjectileMovement subobject **/
   UProjectileMovementComponent* GetProjectileMovement() const { return ProjectileMovement; }
       };

Here is the projectile.cpp file:

      #include "FPSProjectile.h"
       #include "GameFramework/ProjectileMovementComponent.h"  
        #include "Components/SphereComponent.h"

      AFPSProjectile::AFPSProjectile() 
      {
    // Use a sphere as a simple collision representation
     CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComp"));
     	CollisionComp->InitSphereRadius(5.0f);
       CollisionComp->SetCollisionProfileName("Projectile");

          CollisionComp->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);	
                // set up a notification for when this component hits something 

`

           // Players can't walk on it
   CollisionComp->SetWalkableSlopeOverride(FWalkableSlopeOverride(WalkableSlope_Unwalkable, 0.f));
    CollisionComp->CanCharacterStepUpOn = ECB_No;

  // Set as root component
  RootComponent = CollisionComp;

 // Use a ProjectileMovementComponent to govern this projectile's 
 ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
  ProjectileMovement->UpdatedComponent = CollisionComp;
  ProjectileMovement->InitialSpeed = 3000.f;
   ProjectileMovement->MaxSpeed = 3000.f;
    ProjectileMovement->bRotationFollowsVelocity = true;
    ProjectileMovement->bShouldBounce = true;

   // Die after 3 seconds by default
    InitialLifeSpan = 3.0f;
      }


      void AFPSProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* 
       OtherComp, FVector NormalImpulse, const FHitResult& Hit)
         {
    // Only add impulse and destroy projectile if we hit a physics
    if ((OtherActor !=	NULL) && (OtherActor != this) && (OtherComp != NULL) && OtherComp- 
         >IsSimulatingPhysics())
       {
         	OtherComp->AddImpulseAtLocation(GetVelocity() * 100.0f, GetActorLocation());
	
	      Destroy();
     }
      }
1 Like

Don’t bind the delegate in the constructor as it’s not reliable. Move the following line from the constructor to e.g. BeginPlay:

CollisionComp->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);  

You can override BeginPlay by adding the following to your header:

public:
        virtual void BeginPlay() override;

and implement it in your cpp file as follows:

void AFPSProjectile::BeginPlay()
{
            // Always remember to call Super
    	    Super::BeginPlay();
    
            // Bind delegate
            CollisionComp->OnComponentHit.AddDynamic(this, &AFPSProjectile::OnHit);
}
1 Like

Thx Man! This is really helpful!