quinta-feira, 15 de abril de 2021

EnemyCannon: Counting the Hits

In this article, we are going to add a hit count to the EnemyCannon class. When the number of Hits reaches a specified maximum value, the EnemyCannon instance will be destroyed.

We will use two integer variables. NumHits will store the number of times an EnemyCannon has been hit and MaxHits will store the number of hits needed to destroy an EnemyCannon.

We will use the NotifyHit() event/function to increment NumHits. This event is called when an EnemyCannon is hit.

The Cannon destruction is done by the DestroyCannon() function. It is a UFUNCTION() of type BlueprintNativeEvent that allows a default C++ implementation that will be used if the Blueprint version of the function is not implemented. For more information about UFUNCTION(), visit this link.

The 1st version of the EnemyCannon.h file was created at this link.

Add the declaration of the new variables and functions in the EnemyCannon.h file below the ShootCannon() function:

...
  FTimerHandle ShotTimerHandle;
	
  void ShootCannon();	

  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Cannon)
  int32 MaxHits;
	
  UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Cannon)
  int32 NumHits;

  UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = Cannon)
  void DestroyCannon();
	
  virtual void NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other, 
          class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation, 
          FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit) override;

};

The next step is to modify the EnemyCannon.cpp file that was created at this link.

In the constructor, initialize the MaxHits variable with a value of 5:

FireRate = 5.f;	
MaxHits = 5;

Add the implementation of the NotifyHit() and DestroyCannon_Implementation() functions at the end of the EnemyCannon.cpp file:

void AEnemyCannon::NotifyHit(class UPrimitiveComponent* MyComp, class AActor* Other,
           class UPrimitiveComponent* OtherComp, bool bSelfMoved, FVector HitLocation,
           FVector HitNormal, FVector NormalImpulse, const FHitResult& Hit)
{
  Super::NotifyHit(MyComp, Other, OtherComp, bSelfMoved, HitLocation, HitNormal, 
                   NormalImpulse, Hit);
	
  if (Cast<APlayerProjectile>(Other) != nullptr)
  {
    NumHits++;
		
    if( NumHits == MaxHits )
    {
      DestroyCannon();
    }
  }
}

void AEnemyCannon::DestroyCannon_Implementation()
{
  Destroy();
}

In the NotifyHit() function, a Cast<APlayerProjectile>(Other) is used because we will only count a Hit if the EnemyCannon is hit by a projectile of the type APlayerProjectile (or child classes).

When the value of the NumHits variable is equal to MaxHits, the DestroyCannon() function will be called.

Note that the implementation of the DestroyCannon() function has the suffix _Implementation. This suffix is necessary because it is a BlueprintNativeEvent.


Table of Contents C++