198 - Projectile Server-Side Rewind

This commit is contained in:
Kingsmedia 2022-05-28 00:28:02 +02:00
parent e619252c4c
commit 4ae87bee2a
3 changed files with 120 additions and 16 deletions

View File

@ -213,9 +213,82 @@ FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackag
return FServerSideRewindResult{ false, false }; return FServerSideRewindResult{ false, false };
} }
FServerSideRewindResult ULagCompensationComponent::ProjectileConfirmHit(const FFramePackage& Package, ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity, float HitTime)
{
FFramePackage CurrentFrame;
CacheBoxPositions(HitCharacter, CurrentFrame);
MoveBoxes(HitCharacter, Package);
EnableCharacterMeshCollision(HitCharacter, ECollisionEnabled::NoCollision);
// Enable collision for the head first
UBoxComponent* HeadBox = HitCharacter->HitCollisionBoxes[FName("head")];
HeadBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
HeadBox->SetCollisionResponseToChannel(ECC_HitBox, ECR_Block);
FPredictProjectilePathParams PathParams;
PathParams.bTraceWithCollision = true;
PathParams.MaxSimTime = MaxRecordTime;
PathParams.LaunchVelocity = InitialVelocity;
PathParams.StartLocation = TraceStart;
PathParams.SimFrequency = 15.f;
PathParams.ProjectileRadius = 5.f;
PathParams.TraceChannel = ECC_HitBox;
PathParams.ActorsToIgnore.Add(GetOwner());
PathParams.DrawDebugTime = 5.f;
PathParams.DrawDebugType = EDrawDebugTrace::ForDuration;
FPredictProjectilePathResult PathResult;
UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult);
if (PathResult.HitResult.bBlockingHit) // we hit the head, return early
{
if (PathResult.HitResult.Component.IsValid())
{
UBoxComponent* Box = Cast<UBoxComponent>(PathResult.HitResult.Component);
if (Box)
{
DrawDebugBox(GetWorld(), Box->GetComponentLocation(), Box->GetScaledBoxExtent(), FQuat(Box->GetComponentRotation()), FColor::Red, false, 8.f);
}
}
ResetHitBoxes(HitCharacter, CurrentFrame);
EnableCharacterMeshCollision(HitCharacter, ECollisionEnabled::QueryAndPhysics);
return FServerSideRewindResult{ true, true };
}
// we didn't hit the head; check the rest of the boxes
for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
{
if (HitBoxPair.Value != nullptr)
{
HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
HitBoxPair.Value->SetCollisionResponseToChannel(ECC_HitBox, ECR_Block);
}
}
UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult);
if (PathResult.HitResult.bBlockingHit)
{
if (PathResult.HitResult.Component.IsValid())
{
UBoxComponent* Box = Cast<UBoxComponent>(PathResult.HitResult.Component);
if (Box)
{
DrawDebugBox(GetWorld(), Box->GetComponentLocation(), Box->GetScaledBoxExtent(), FQuat(Box->GetComponentRotation()), FColor::Blue, false, 8.f);
}
}
ResetHitBoxes(HitCharacter, CurrentFrame);
EnableCharacterMeshCollision(HitCharacter, ECollisionEnabled::QueryAndPhysics);
return FServerSideRewindResult{ true, false };
}
ResetHitBoxes(HitCharacter, CurrentFrame);
EnableCharacterMeshCollision(HitCharacter, ECollisionEnabled::QueryAndPhysics);
return FServerSideRewindResult{ false, false };
}
FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(const TArray<FFramePackage>& FramePackages, FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(const TArray<FFramePackage>& FramePackages,
const FVector_NetQuantize& TraceStart, const TArray<FVector_NetQuantize>& HitLocations) const FVector_NetQuantize& TraceStart, const TArray<FVector_NetQuantize>& HitLocations)
{ {
for (auto& Frame : FramePackages) for (auto& Frame : FramePackages)
{ {
@ -415,6 +488,13 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar
return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation); return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
} }
FServerSideRewindResult ULagCompensationComponent::ProjectilServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity, float HitTime)
{
const FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime);
return ProjectileConfirmHit(FrameToCheck, HitCharacter, TraceStart, InitialVelocity, HitTime);
}
FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunServerSideRewind(const TArray<ABlasterCharacter*>& HitCharacters, FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunServerSideRewind(const TArray<ABlasterCharacter*>& HitCharacters,
const FVector_NetQuantize& TraceStart, const TArray<FVector_NetQuantize>& HitLocations, float HitTime) const FVector_NetQuantize& TraceStart, const TArray<FVector_NetQuantize>& HitLocations, float HitTime)
{ {

View File

@ -71,13 +71,32 @@ public:
friend ABlasterCharacter; friend ABlasterCharacter;
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void ShowFramePackage(const FFramePackage& Package, const FColor Color); void ShowFramePackage(const FFramePackage& Package, const FColor Color);
// Hitscan
FServerSideRewindResult ServerSideRewind( FServerSideRewindResult ServerSideRewind(
ABlasterCharacter* HitCharacter, ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize& HitLocation, const FVector_NetQuantize& HitLocation,
float HitTime float HitTime
); );
// Projectiles
FServerSideRewindResult ProjectilServerSideRewind(
ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity,
float HitTime
);
// Shotgun
UFUNCTION(Server, Reliable)
void ShotgunServerScoreRequest(
const TArray<ABlasterCharacter*>& HitCharacters,
const FVector_NetQuantize& TraceStart,
const TArray<FVector_NetQuantize>& HitLocations,
float HitTime
);
UFUNCTION(Server, Reliable) UFUNCTION(Server, Reliable)
void ServerScoreRequest( void ServerScoreRequest(
ABlasterCharacter* HitCharacter, ABlasterCharacter* HitCharacter,
@ -87,14 +106,6 @@ public:
AWeapon* DamageCauser AWeapon* DamageCauser
); );
UFUNCTION(Server, Reliable)
void ShotgunServerScoreRequest(
const TArray<ABlasterCharacter*>& HitCharacters,
const FVector_NetQuantize& TraceStart,
const TArray<FVector_NetQuantize>& HitLocations,
float HitTime
);
FShotgunServerSideRewindResult ShotgunServerSideRewind( FShotgunServerSideRewindResult ShotgunServerSideRewind(
const TArray<ABlasterCharacter*>& HitCharacters, const TArray<ABlasterCharacter*>& HitCharacters,
const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& TraceStart,
@ -107,20 +118,31 @@ protected:
void SaveFramePackage(); void SaveFramePackage();
void SaveFramePackage(FFramePackage& Package); void SaveFramePackage(FFramePackage& Package);
FFramePackage InterpBetweenFrames(const FFramePackage& OlderFrame, const FFramePackage& YoungerFrame, float HitTime); FFramePackage InterpBetweenFrames(const FFramePackage& OlderFrame, const FFramePackage& YoungerFrame, float HitTime);
FServerSideRewindResult ConfirmHit(
const FFramePackage& Package,
ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize HitLocation
);
void CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage); void CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage);
void MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package); void MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package);
void ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package); void ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package);
void EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled); void EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled);
FFramePackage GetFrameToCheck(ABlasterCharacter* HitCharacter, float HitTime); FFramePackage GetFrameToCheck(ABlasterCharacter* HitCharacter, float HitTime);
// Shotgun related stuff // Hitscan
FServerSideRewindResult ConfirmHit(
const FFramePackage& Package,
ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize HitLocation
);
// Projectile
FServerSideRewindResult ProjectileConfirmHit(
const FFramePackage& Package,
ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize100& InitialVelocity,
float HitTime
);
// Shotgun
FShotgunServerSideRewindResult ShotgunConfirmHit( FShotgunServerSideRewindResult ShotgunConfirmHit(
const TArray<FFramePackage>& FramePackages, const TArray<FFramePackage>& FramePackages,
const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& TraceStart,

View File

@ -52,6 +52,7 @@ void AProjectileBullet::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
/*
FPredictProjectilePathParams PathParams; FPredictProjectilePathParams PathParams;
PathParams.bTraceWithChannel = true; PathParams.bTraceWithChannel = true;
PathParams.bTraceWithCollision = true; PathParams.bTraceWithCollision = true;
@ -67,4 +68,5 @@ void AProjectileBullet::BeginPlay()
FPredictProjectilePathResult PathResult; FPredictProjectilePathResult PathResult;
UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult); UGameplayStatics::PredictProjectilePath(this, PathParams, PathResult);
*/
} }