Add health component and damage handler to the ball
//生命值组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
class USHealthComponent * HealthComp;
//伤害处理函数
UFUNCTION()
void HandleTakeAnyDamage(USHealthComponent * OwnerHealthComp, float Health, float HealthDelta, const UDamageType * DamageType, AController * InstigatedBy, AActor * DamageCauser);
Create components and define functions
HealthComp = CreateDefaultSubobject<USHealthComponent>(TEXT("HealthComp"));
void AASTrackerBot::HandleTakeAnyDamage(USHealthComponent * OwnerHealthComp, float Health, float HealthDelta, const UDamageType * DamageType, AController * InstigatedBy, AActor * DamageCauser)
{
UKismetSystemLibrary::PrintString(this, FString::SanitizeFloat(HealthComp->Health));
}
Add explosion-related member variables and functions
//自爆函数
void SelfDestruct();
//爆炸特效
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
class UParticleSystem * ExplorEffect;
//是否已经爆炸
bool bExplored;
//爆炸半径
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
float ExplorRadius;
//爆炸伤害
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
float ExplorDamage;
Initialize it in the constructor
bExplored = false;
ExplorRadius = 200;
ExplorDamage = 100;
Define the self-destruct function
void AASTrackerBot::SelfDestruct()
{
//检查是否已经爆炸了
if (bExplored)
{
return;
}
bExplored = true;
//发生爆炸
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ExplorEffect, GetActorLocation());
//设置要忽略的actor
TArray<AActor * > IgnoredActors;
IgnoredActors.Add(this);
//对自身进行伤害
UGameplayStatics::ApplyRadialDamage(this, ExplorDamage, GetActorLocation(), ExplorRadius, nullptr, IgnoredActors, this, GetInstigatorController(), true);
//画出伤害范围
DrawDebugSphere(GetWorld(), GetActorLocation(), ExplorRadius, 12, FColor::Green, false, 2.0f, 0, 1.0f);
//自毁
Destroy();
}
In damage handling, call this function
void AASTrackerBot::HandleTakeAnyDamage(USHealthComponent * OwnerHealthComp, float Health, float HealthDelta, const UDamageType * DamageType, AController * InstigatedBy, AActor * DamageCauser)
{
UKismetSystemLibrary::PrintString(this, FString::SanitizeFloat(HealthComp->Health));
if (HealthComp->Health <= 0)
{
SelfDestruct();
}
}
===========================================
Now implements the timing self-detonation function when approaching the player
Create related variables and functions
//球形碰撞组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
class USphereComponent* CollisionComponent;
//自爆倒计时句柄
FTimerHandle TimerHandle_SelfDamage;
//倒计时自爆函数
void DamageSelf();
//是否已经开始自毁倒计时
bool bStartSelfDamge;
//游戏重叠函数
virtual void NotifyActorBeginOverlap(AActor * OtherActor) override;
Create a spherical component in the constructor and set related parameters
CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
CollisionComponent->SetSphereRadius(200);
CollisionComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
CollisionComponent->SetCollisionResponseToAllChannels(ECR_Ignore);
CollisionComponent->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
CollisionComponent->SetupAttachment(RootComponent);
Define the countdown self-destruct function
void AASTrackerBot::DamageSelf()
{
UGameplayStatics::ApplyDamage(this, 20, GetInstigatorController(), this, nullptr);
}
define overlap function
void AASTrackerBot::NotifyActorBeginOverlap(AActor * OtherActor)
{
if (!bStartSelfDamge)
{
ASCharacter * PlayerPawn = Cast<ASCharacter>(OtherActor);
if (PlayerPawn)
{
GetWorld()->GetTimerManager().SetTimer(TimerHandle_SelfDamage, this, &AASTrackerBot::DamageSelf, 0.5f, true , 0.0f);
bStartSelfDamge = true;
}
}
}
Compile, then open the blueprint of the ball, select special effects
Compile, test, and find that the ball will not explode.
Put the event binding function of the constructor into the game start function. that's it
// Called when the game starts or when spawned
void AASTrackerBot::BeginPlay()
{
Super::BeginPlay();
NextPathPoint = GetNextPathPoint();
//伤害事件绑定函数
HealthComp->OnHealthChanged.AddDynamic(this, &AASTrackerBot::HandleTakeAnyDamage);
}
I don't know why.
It can also kill people.
========================================
Now let's refine the material for the ball
Hold down T and click the left mouse button
then choose a material
Press U, then click the left mouse button
Set these two to 4
This makes the material denser
Hold down M, then click the left mouse button to get the multiplication node, and then connect
Press and hold 1, then click the left mouse button to generate a constant node, and then connect it to the self-illumination
This is the effect of setting the value to 0.5
Add a Time node
Then hold down s and click the left mouse button to generate a parameter node
We use (time - parameter) * 4, and then constrain the product.
Then 1- the above result
and then get an index
and then assign it to self-illumination
Back to the ball class, we add a variable for the material of the ball
//动态材质
class UMaterialInstanceDynamic * MatInst;
#include "Materials/MaterialInstanceDynamic.h"
Improve the damage processing function
void AASTrackerBot::HandleTakeAnyDamage(USHealthComponent * OwnerHealthComp, float Health, float HealthDelta, const UDamageType * DamageType, AController * InstigatedBy, AActor * DamageCauser)
{
//UKismetSystemLibrary::PrintString(this, FString::SanitizeFloat(HealthComp->Health));
//得到MeshComponent组件的材质
if (MatInst == nullptr)
{
MatInst = MeshComponent->CreateAndSetMaterialInstanceDynamicFromMaterial(0, MeshComponent->GetMaterial(0));
UKismetSystemLibrary::PrintString(this, FString::SanitizeFloat(HealthComp->Health));
}
//将参数设为当前时间,让材质发光
if (MatInst)
{
MatInst->SetScalarParameterValue("LastTimeDamageTaken", GetWorld()->TimeSeconds);
}
//自爆
if (HealthComp->Health <= 0)
{
SelfDestruct();
}
}
==========================================
Now add sound effects
Add two member variables
//自爆中声音特效
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
class USoundCue * SelfDestructSound;
//爆炸特效
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
class USoundCue * ExploedSound;
#include "Sound/SoundCue.h"
Update the SelfDestruct function and the NotifyActorBeginOverlap function
void AASTrackerBot::SelfDestruct()
{
//检查是否已经爆炸了
if (bExplored)
{
return;
}
bExplored = true;
//发生爆炸
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ExplorEffect, GetActorLocation());
//设置要忽略的actor
TArray<AActor * > IgnoredActors;
IgnoredActors.Add(this);
// UKismetSystemLibrary::PrintString(this, FString::SanitizeFloat(222.0f));
//对自身进行伤害
UGameplayStatics::ApplyRadialDamage(this, ExplorDamage, GetActorLocation(), ExplorRadius, nullptr, IgnoredActors, this, GetInstigatorController(), true);
//画出伤害范围
DrawDebugSphere(GetWorld(), GetActorLocation(), ExplorRadius, 12, FColor::Green, false, 2.0f, 0, 1.0f);
//发生爆炸声,在actor的位置
UGameplayStatics::PlaySoundAtLocation(this, ExploedSound, GetActorLocation());
//自毁
Destroy();
}
void AASTrackerBot::NotifyActorBeginOverlap(AActor * OtherActor)
{
if (!bStartSelfDamge)
{
ASCharacter * PlayerPawn = Cast<ASCharacter>(OtherActor);
if (PlayerPawn)
{
GetWorld()->GetTimerManager().SetTimer(TimerHandle_SelfDamage, this, &AASTrackerBot::DamageSelf, 0.5f, true , 0.0f);
bStartSelfDamge = true;
}
//将自爆警告声音绑定到根组件
UGameplayStatics::SpawnSoundAttached(SelfDestructSound, RootComponent);
}
}
Delete these finished products, let's make one ourselves
Create cue, cue is actually a subclass of sound file
Set sound attenuation
We can also do a sound attenuation
Open after creation, set to natural sound
Choose attenuation here
Select sound in blueprint
Then add a sound component, select the scrolling sound effect
Compilation test succeeded