一句话,跟掉血有关的代码都在服务器端执行
修改小球的游戏开始函数
在服务器端,小球自动寻找路径
void AASTrackerBot::BeginPlay()
{
Super::BeginPlay();
if (Role == ROLE_Authority)
{
NextPathPoint = GetNextPathPoint();
}
//伤害事件绑定函数
HealthComp->OnHealthChanged.AddDynamic(this, &AASTrackerBot::HandleTakeAnyDamage);
}
修改SelfDestruct函数
在服务器端小球会对自己施加伤害
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));
//伤害在服务器中执行
if (Role == ROLE_Authority)
{
//对自身进行伤害
UGameplayStatics::ApplyRadialDamage(this, ExplorDamage, GetActorLocation(), ExplorRadius, nullptr, IgnoredActors, this, GetInstigatorController(), true);
SetLifeSpan(2.0f);
}
//画出伤害范围
DrawDebugSphere(GetWorld(), GetActorLocation(), ExplorRadius, 12, FColor::Green, false, 2.0f, 0, 1.0f);
//发生爆炸声,在actor的位置
UGameplayStatics::PlaySoundAtLocation(this, ExploedSound, GetActorLocation());
//自毁
//Destroy();
MeshComponent->SetVisibility(false, true);
MeshComponent->SetSimulatePhysics(false);
MeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}
修改每帧函数
在服务器端,小球自动寻找路径
void AASTrackerBot::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// UKismetSystemLibrary::PrintString(this, FString::SanitizeFloat(HealthComp->Health));
//得到小球自身与下一个点的距离
if (Role == ROLE_Authority && !bExplored)
{
float DistanceToTarget = (NextPathPoint - GetActorLocation()).Size();
//如果大于阈值,就继续滚
if (DistanceToTarget > RequiredDistanceToTarget)
{
//小球的移动方向
FVector ForceDirection = NextPathPoint - GetActorLocation();
ForceDirection.Normalize();
//小球的推力
ForceDirection *= MovementForce;
MeshComponent->ComponentVelocity.Size();
MeshComponent->AddImpulse(ForceDirection, NAME_None, bUseVelocityChange);
DrawDebugDirectionalArrow(GetWorld(), GetActorLocation(), GetActorLocation() + ForceDirection, 32, FColor::Red, false, 0.0f, 0, 1.0f);
}
//如果到达了路径点,就生成下一个点,继续移动
else
{
NextPathPoint = GetNextPathPoint();
DrawDebugString(GetWorld(), GetActorLocation(), "Target Reached!");
}
//在下一个目标点画一个球
DrawDebugSphere(GetWorld(), NextPathPoint, 20, 12, FColor::Yellow, false, 0.0f, 0, 1.0f);
}
}
修改重叠函数
在服务器端,小球自爆倒计时
void AASTrackerBot::NotifyActorBeginOverlap(AActor * OtherActor)
{
if (!bStartSelfDamge)
{
ASCharacter * PlayerPawn = Cast<ASCharacter>(OtherActor);
if (PlayerPawn)
{
if (Role == ROLE_Authority)
{
GetWorld()->GetTimerManager().SetTimer(TimerHandle_SelfDamage, this, &AASTrackerBot::DamageSelf, 0.5f, true, 0.0f);
}
bStartSelfDamge = true;
}
//将自爆警告声音绑定到根组件
UGameplayStatics::SpawnSoundAttached(SelfDestructSound, RootComponent);
}
}
修改生命值组件
//当前生命值
UPROPERTY(ReplicatedUsing = OnRep_Health, BlueprintReadOnly, Category = "HealthComponent")
float Health;
添加网络同步函数
//生命值同步函数
UFUNCTION()
void OnRep_Health(float OldHealth);
实现一下
void USHealthComponent::OnRep_Health(float OldHealth)
{
//触发自定义事件
OnHealthChanged.Broadcast(this, Health, OldHealth - Health , nullptr, nullptr, nullptr);
}
为什么要这样同步一下呢
文章来源:https://www.toymoban.com/news/detail-550266.html
文章来源地址https://www.toymoban.com/news/detail-550266.html
到了这里,关于21uec++多人游戏【AI联机】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!