20uec++ multiplayer game [ball interacts with players]

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  

Guess you like

Origin blog.csdn.net/zhang2362167998/article/details/128097328