190 - Server-Side Rewind for Shotguns
This commit is contained in:
parent
de7d73125b
commit
eec38a37db
|
@ -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)
|
void ULagCompensationComponent::SaveFramePackage(FFramePackage& Package)
|
||||||
{
|
{
|
||||||
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : Character;
|
Character = Character == nullptr ? Cast<ABlasterCharacter>(GetOwner()) : Character;
|
||||||
if (Character)
|
if (Character)
|
||||||
{
|
{
|
||||||
Package.Time = GetWorld()->GetTimeSeconds();
|
Package.Time = GetWorld()->GetTimeSeconds();
|
||||||
|
Package.Character = Character;
|
||||||
for (auto& BoxPair : Character->HitCollisionBoxes)
|
for (auto& BoxPair : Character->HitCollisionBoxes)
|
||||||
{
|
{
|
||||||
FBoxInformation BoxInformation;
|
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,
|
FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation,
|
||||||
float HitTime)
|
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 ||
|
bool bReturn = HitCharacter == nullptr ||
|
||||||
HitCharacter->GetLagCompensation() == nullptr ||
|
HitCharacter->GetLagCompensation() == nullptr ||
|
||||||
HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr ||
|
HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr ||
|
||||||
HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr;
|
HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr;
|
||||||
|
|
||||||
if (bReturn) FServerSideRewindResult();
|
if (bReturn) FFramePackage();
|
||||||
|
|
||||||
// Frame package that we check to verify a hit
|
// Frame package that we check to verify a hit
|
||||||
FFramePackage FrameToCheck;
|
FFramePackage FrameToCheck;
|
||||||
|
@ -228,7 +277,7 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar
|
||||||
if (OldestHistoryTime > HitTime)
|
if (OldestHistoryTime > HitTime)
|
||||||
{
|
{
|
||||||
// Too far back, too laggy to do SSR
|
// Too far back, too laggy to do SSR
|
||||||
FServerSideRewindResult();
|
FFramePackage();
|
||||||
}
|
}
|
||||||
if (OldestHistoryTime == HitTime)
|
if (OldestHistoryTime == HitTime)
|
||||||
{
|
{
|
||||||
|
@ -259,11 +308,11 @@ FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterChar
|
||||||
|
|
||||||
if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr?
|
if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr?
|
||||||
{
|
{
|
||||||
// Interpolate between Younger and Older
|
// Interpolate between Younger and Older
|
||||||
FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
|
FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
|
return FrameToCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ULagCompensationComponent::EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled)
|
void ULagCompensationComponent::EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled)
|
||||||
|
@ -280,27 +329,3 @@ void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickTy
|
||||||
|
|
||||||
SaveFramePackage();
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -30,7 +30,11 @@ struct FFramePackage
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
float Time;
|
float Time;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
TMap<FName, FBoxInformation> HitBoxInfo;
|
TMap<FName, FBoxInformation> HitBoxInfo;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
ABlasterCharacter* Character;
|
||||||
};
|
};
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
USTRUCT(BlueprintType)
|
||||||
|
@ -45,7 +49,19 @@ struct FServerSideRewindResult
|
||||||
bool bHeadShot;
|
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
|
class BLASTER_API ULagCompensationComponent : public UActorComponent
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
@ -55,7 +71,12 @@ 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);
|
||||||
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)
|
UFUNCTION(Server, Reliable)
|
||||||
void ServerScoreRequest(
|
void ServerScoreRequest(
|
||||||
|
@ -63,20 +84,41 @@ public:
|
||||||
const FVector_NetQuantize& TraceStart,
|
const FVector_NetQuantize& TraceStart,
|
||||||
const FVector_NetQuantize& HitLocation,
|
const FVector_NetQuantize& HitLocation,
|
||||||
float HitTime,
|
float HitTime,
|
||||||
class AWeapon* DamageCauser
|
AWeapon* DamageCauser
|
||||||
);
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
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);
|
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);
|
||||||
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()
|
UPROPERTY()
|
||||||
ABlasterCharacter* Character;
|
ABlasterCharacter* Character;
|
||||||
|
|
||||||
|
@ -87,5 +129,4 @@ private:
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere)
|
UPROPERTY(EditAnywhere)
|
||||||
float MaxRecordTime = 4.f;
|
float MaxRecordTime = 4.f;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue