Add wildlife performance limits

This commit is contained in:
2026-05-18 14:21:34 -07:00
parent 494fe6f2ef
commit a834eb74c4
5 changed files with 151 additions and 2 deletions
+49 -1
View File
@@ -45,7 +45,12 @@ void AAgrarianWildlifeBase::Tick(float DeltaSeconds)
if (HasAuthority())
{
ServerThink(DeltaSeconds);
if (ShouldRunServerThink(DeltaSeconds))
{
const float EffectiveDeltaSeconds = bEnablePerformanceLimits ? ServerThinkAccumulator : DeltaSeconds;
ServerThink(EffectiveDeltaSeconds);
ServerThinkAccumulator = 0.0f;
}
}
}
@@ -134,6 +139,22 @@ void AAgrarianWildlifeBase::OnRep_WildlifeState()
BroadcastStateChanged();
}
bool AAgrarianWildlifeBase::ShouldRunServerThink(float DeltaSeconds)
{
if (!bEnablePerformanceLimits || WildlifeState == EAgrarianWildlifeState::Dead)
{
return true;
}
ServerThinkAccumulator += DeltaSeconds;
if (GetNearestPlayerDistanceSquared() <= FMath::Square(FullUpdateRadius))
{
return true;
}
return ServerThinkAccumulator >= FarUpdateIntervalSeconds;
}
void AAgrarianWildlifeBase::ServerThink(float DeltaSeconds)
{
if (!IsAlive())
@@ -354,6 +375,7 @@ void AAgrarianWildlifeBase::EnterDeadState()
ClearNavigationMove();
GetCharacterMovement()->StopMovementImmediately();
GetCharacterMovement()->DisableMovement();
SetActorTickEnabled(false);
SetLifeSpan(0.0f);
}
@@ -389,6 +411,32 @@ AAgrarianGameCharacter* AAgrarianWildlifeBase::FindNearestPlayer(float Radius) c
return NearestCharacter;
}
float AAgrarianWildlifeBase::GetNearestPlayerDistanceSquared() const
{
UWorld* World = GetWorld();
if (!World)
{
return TNumericLimits<float>::Max();
}
float BestDistanceSq = TNumericLimits<float>::Max();
TArray<AActor*> PlayerPawns;
UGameplayStatics::GetAllActorsOfClass(World, AAgrarianGameCharacter::StaticClass(), PlayerPawns);
for (AActor* Actor : PlayerPawns)
{
const AAgrarianGameCharacter* Candidate = Cast<AAgrarianGameCharacter>(Actor);
if (!Candidate)
{
continue;
}
BestDistanceSq = FMath::Min(BestDistanceSq, FVector::DistSquared(GetActorLocation(), Candidate->GetActorLocation()));
}
return BestDistanceSq;
}
bool AAgrarianWildlifeBase::Harvest(AAgrarianGameCharacter* Interactor)
{
if (!Interactor || WildlifeState != EAgrarianWildlifeState::Dead || bHarvested)
@@ -78,6 +78,15 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Movement")
FVector NavigationProjectionExtent = FVector(500.0f, 500.0f, 900.0f);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Performance")
bool bEnablePerformanceLimits = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Performance", meta = (ClampMin = "0"))
float FullUpdateRadius = 6500.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Performance", meta = (ClampMin = "0.1"))
float FarUpdateIntervalSeconds = 2.5f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Wildlife|Harvest")
TArray<FAgrarianItemStack> HarvestYields;
@@ -106,6 +115,7 @@ protected:
UFUNCTION()
void OnRep_WildlifeState();
bool ShouldRunServerThink(float DeltaSeconds);
void ServerThink(float DeltaSeconds);
void ChooseWanderTarget();
void MoveTowardTarget();
@@ -116,6 +126,7 @@ protected:
void DirectMoveTowardLocation(const FVector& TargetLocation, float MovementSpeed);
void EnterDeadState();
AAgrarianGameCharacter* FindNearestPlayer(float Radius) const;
float GetNearestPlayerDistanceSquared() const;
bool Harvest(AAgrarianGameCharacter* Interactor);
void BroadcastHealthChanged();
void BroadcastStateChanged();
@@ -134,4 +145,5 @@ protected:
bool bHasNavigationMoveTarget = false;
float DecisionTimer = 0.0f;
float ServerThinkAccumulator = 0.0f;
};