为小球添加生命值组件和伤害处理函数
//生命值组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
class USHealthComponent * HealthComp;
//伤害处理函数
UFUNCTION()
void HandleTakeAnyDamage(USHealthComponent * OwnerHealthComp, float Health, float HealthDelta, const UDamageType * DamageType, AController * InstigatedBy, AActor * DamageCauser);
创建组件并定义函数
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));
}
添加与爆炸相关的成员变量和函数
//自爆函数
void SelfDestruct();
//爆炸特效
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
class UParticleSystem * ExplorEffect;
//是否已经爆炸
bool bExplored;
//爆炸半径
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
float ExplorRadius;
//爆炸伤害
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
float ExplorDamage;
在构造函数中初始化一下
bExplored = false;
ExplorRadius = 200;
ExplorDamage = 100;
定义自爆函数
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();
}
在伤害处理中,调用该函数
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();
}
}
===========================================
现在实现靠近玩家定时自爆功能
创建相关的变量和函数
//球形碰撞组件
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
class USphereComponent* CollisionComponent;
//自爆倒计时句柄
FTimerHandle TimerHandle_SelfDamage;
//倒计时自爆函数
void DamageSelf();
//是否已经开始自毁倒计时
bool bStartSelfDamge;
//游戏重叠函数
virtual void NotifyActorBeginOverlap(AActor * OtherActor) override;
在构造函数中创建球形组件,并设置相关参数
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);
定义倒计时自爆函数
void AASTrackerBot::DamageSelf()
{
UGameplayStatics::ApplyDamage(this, 20, GetInstigatorController(), this, nullptr);
}
定义重叠函数
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;
}
}
}
编译,然后打开小球的蓝图,选择特效
编译,测试,发现小球不会爆炸。
将构造函数的事件绑定函数放到游戏开始函数。就可以了
// Called when the game starts or when spawned
void AASTrackerBot::BeginPlay()
{
Super::BeginPlay();
NextPathPoint = GetNextPathPoint();
//伤害事件绑定函数
HealthComp->OnHealthChanged.AddDynamic(this, &AASTrackerBot::HandleTakeAnyDamage);
}
我也不知道为啥。
同时也可以炸死人。
========================================
现在我们为小球完善一下材质
按住T,点击鼠标左键
然后选择一个材质
按U,然后点击鼠标左键
将这两个设成4
这样可以让材质变得密集
按住M,然后点击鼠标左键,得到乘节点,然后连线
按住1,然后点击鼠标左键,生成常数节点,然后连接到自发光上面
这是将值设为0.5的效果
添加一个Time节点
然后按住s,点击鼠标左键,生成参数节点
我们用(时间-参数)*4,然后约束一下乘积。
然后1-上述结果
然后再得到一个指数
然后将其赋予到自发光上面
回到小球类,我们添加一个小球材质的变量
//动态材质
class UMaterialInstanceDynamic * MatInst;
#include "Materials/MaterialInstanceDynamic.h"
完善伤害处理函数
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();
}
}
==========================================
现在加一下声音特效
添加两个成员变量
//自爆中声音特效
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
class USoundCue * SelfDestructSound;
//爆炸特效
UPROPERTY(EditDefaultsOnly, Category = "TracerBot")
class USoundCue * ExploedSound;
#include "Sound/SoundCue.h"
更新一下SelfDestruct函数和NotifyActorBeginOverlap函数
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);
}
}
删掉这些成品,我们自己做一个
创建cue, cue实际上就是声音文件的子类
设置声音衰减
我们还可以做一个音效衰减
创建之后打开,设为自然音
这里选择衰减
在蓝图中选择声音
然后添加一个声音组件,选择滚动声效
编译测试成功