190 - Server-Side Rewind for Shotguns

This commit is contained in:
Kingsmedia 2022-05-27 19:13:59 +02:00
parent de7d73125b
commit eec38a37db
2 changed files with 102 additions and 36 deletions

View File

@ -36,12 +36,37 @@ void ULagCompensationComponent::ServerScoreRequest_Implementation(ABlasterCharac
}
}
void ULagCompensationComponent::SaveFramePackage()
{
if (Character == nullptr || !Character->HasAuthority()) return;
if (FrameHistory.Num() <= 1)
{
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
}
else
{
float HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
while (HistoryLength > MaxRecordTime)
{
FrameHistory.RemoveNode(FrameHistory.GetTail());
HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
}
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
// ShowFramePackage(ThisFrame, FColor::Red);
}
}
void ULagCompensationComponent::SaveFramePackage(FFramePackage& Package)
{
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : Character;
if (Character)
{
Package.Time = GetWorld()->GetTimeSeconds();
Package.Character = Character;
for (auto& BoxPair : Character->HitCollisionBoxes)
{
FBoxInformation BoxInformation;
@ -210,13 +235,37 @@ void ULagCompensationComponent::ShowFramePackage(const FFramePackage& Package, c
FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation,
float HitTime)
{
const FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime);
return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
}
FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunServerSideRewind(const TArray<ABlasterCharacter*>& HitCharacters,
const FVector_NetQuantize& TraceStart, const TArray<FVector_NetQuantize>& HitLocations, float HitTime)
{
TArray<FFramePackage> FramesToCheck;
for (ABlasterCharacter* HitCharacter : HitCharacters)
{
FramesToCheck.Add(GetFrameToCheck(HitCharacter, HitTime));
}
return FShotgunServerSideRewindResult();
}
FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(const TArray<FFramePackage>& FramePackages,
const FVector_NetQuantize& TraceStart, const TArray<FVector_NetQuantize>& HitLocations)
{
}
FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitCharacter, float HitTime)
{
bool bReturn = HitCharacter == nullptr ||
HitCharacter->GetLagCompensation() == nullptr ||
HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr ||
HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr;
if (bReturn) FServerSideRewindResult();
if (bReturn) FFramePackage();
// Frame package that we check to verify a hit
FFramePackage FrameToCheck;
@ -228,7 +277,7 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar
if (OldestHistoryTime > HitTime)
{
// Too far back, too laggy to do SSR
FServerSideRewindResult();
FFramePackage();
}
if (OldestHistoryTime == HitTime)
{
@ -259,11 +308,11 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar
if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr?
{
// Interpolate between Younger and Older
FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
// Interpolate between Younger and Older
FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
}
return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
return FrameToCheck;
}
void ULagCompensationComponent::EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled)
@ -280,27 +329,3 @@ void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickTy
SaveFramePackage();
}
void ULagCompensationComponent::SaveFramePackage()
{
if (Character == nullptr || !Character->HasAuthority()) return;
if (FrameHistory.Num() <= 1)
{
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
}
else
{
float HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
while (HistoryLength > MaxRecordTime)
{
FrameHistory.RemoveNode(FrameHistory.GetTail());
HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time;
}
FFramePackage ThisFrame;
SaveFramePackage(ThisFrame);
FrameHistory.AddHead(ThisFrame);
// ShowFramePackage(ThisFrame, FColor::Red);
}
}

View File

@ -30,7 +30,11 @@ struct FFramePackage
UPROPERTY()
float Time;
UPROPERTY()
TMap<FName, FBoxInformation> HitBoxInfo;
UPROPERTY()
ABlasterCharacter* Character;
};
USTRUCT(BlueprintType)
@ -45,17 +49,34 @@ struct FServerSideRewindResult
bool bHeadShot;
};
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
USTRUCT(BlueprintType)
struct FShotgunServerSideRewindResult
{
GENERATED_BODY()
UPROPERTY()
TMap<ABlasterCharacter*, uint32> Headshots;
UPROPERTY()
TMap<ABlasterCharacter*, uint32> BodyShots;
};
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
class BLASTER_API ULagCompensationComponent : public UActorComponent
{
GENERATED_BODY()
public:
public:
ULagCompensationComponent();
friend ABlasterCharacter;
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
void ShowFramePackage(const FFramePackage& Package, const FColor Color);
FServerSideRewindResult ServerSideRewind(class ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation, float HitTime);
FServerSideRewindResult ServerSideRewind(
ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize& HitLocation,
float HitTime
);
UFUNCTION(Server, Reliable)
void ServerScoreRequest(
@ -63,20 +84,41 @@ public:
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize& HitLocation,
float HitTime,
class AWeapon* DamageCauser
AWeapon* DamageCauser
);
protected:
virtual void BeginPlay() override;
void SaveFramePackage();
void SaveFramePackage(FFramePackage& Package);
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);
FServerSideRewindResult ConfirmHit(
const FFramePackage& Package,
ABlasterCharacter* HitCharacter,
const FVector_NetQuantize& TraceStart,
const FVector_NetQuantize HitLocation
);
void CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage);
void MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package);
void ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package);
void EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled);
private:
FFramePackage GetFrameToCheck(ABlasterCharacter* HitCharacter, float HitTime);
// Shotgun related stuff
FShotgunServerSideRewindResult ShotgunServerSideRewind(
const TArray<ABlasterCharacter*>& HitCharacters,
const FVector_NetQuantize& TraceStart,
const TArray<FVector_NetQuantize>& HitLocations,
float HitTime
);
FShotgunServerSideRewindResult ShotgunConfirmHit(
const TArray<FFramePackage>& FramePackages,
const FVector_NetQuantize& TraceStart,
const TArray<FVector_NetQuantize>& HitLocations
);
private:
UPROPERTY()
ABlasterCharacter* Character;
@ -87,5 +129,4 @@ private:
UPROPERTY(EditAnywhere)
float MaxRecordTime = 4.f;
};