Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Fill out your copyright notice in the Description page of Project Settings.
- #include "LagCompensationComponent.h"
- #include "Components/BoxComponent.h"
- #include "ShooterProject/Character/BlasterCharacter.h"
- #include "Kismet/GameplayStatics.h"
- #include "DrawDebugHelpers.h"
- #include "ShooterProject/Weapon/Weapon.h"
- #include "ShooterProject/ShooterProject.h"
- ULagCompensationComponent::ULagCompensationComponent()
- {
- PrimaryComponentTick.bCanEverTick = true;
- }
- void ULagCompensationComponent::BeginPlay()
- {
- Super::BeginPlay();
- FFramePackage Package;
- SaveFramePackage(Package);
- ShowFramePackage(Package, FColor::Orange);
- }
- FFramePackage ULagCompensationComponent::InterpBetweenFrames(const FFramePackage& OlderFrame,
- const FFramePackage& YoungerFrame, float HitTime)
- {
- const float Distance = YoungerFrame.Time - OlderFrame.Time;
- const float InterpFraction = FMath::Clamp((HitTime - OlderFrame.Time) / Distance, 0.f, 1.f);
- FFramePackage InterpFramePackage;
- InterpFramePackage.Time = HitTime;
- for(auto& YoungerPair : YoungerFrame.HitBoxInfo)
- {
- const FName& BoxInfoName = YoungerPair.Key;
- const FBoxInformation& OlderBox = OlderFrame.HitBoxInfo[BoxInfoName];
- const FBoxInformation& YoungerBox = YoungerFrame.HitBoxInfo[BoxInfoName];
- FBoxInformation InterpBoxInfo;
- InterpBoxInfo.Location = FMath::VInterpTo(OlderBox.Location,YoungerBox.Location,1.f,InterpFraction);
- InterpBoxInfo.Rotation = FMath::RInterpTo(OlderBox.Rotation, YoungerBox.Rotation, 1.f,InterpFraction);
- InterpBoxInfo.BoxExtent = YoungerBox.BoxExtent;
- InterpFramePackage.HitBoxInfo.Add(BoxInfoName, InterpBoxInfo);
- }
- return InterpFramePackage;
- }
- FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackage& Package,
- ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation)
- {
- if (HitCharacter == nullptr) return FServerSideRewindResult();
- 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::QueryAndPhysics);
- HeadBox->SetCollisionResponseToChannel(ECC_HitBox, ECR_Block);
- FHitResult ConfirmHitResult;
- const FVector TraceEnd = TraceStart + (HitLocation - TraceStart) * 1.25f;
- UWorld* World = GetWorld();
- if (World)
- {
- World->LineTraceSingleByChannel(
- ConfirmHitResult,
- TraceStart,
- TraceEnd,
- ECC_HitBox
- );
- if (ConfirmHitResult.bBlockingHit) // We hit head return early
- {
- if (ConfirmHitResult.Component.IsValid())
- {
- UBoxComponent* Box = Cast<UBoxComponent>(ConfirmHitResult.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};
- }
- else // didn't hit the head, check the rest of the boxes
- {
- for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
- {
- if (HitBoxPair.Value != nullptr)
- {
- HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
- HitBoxPair.Value->SetCollisionResponseToChannel(ECC_HitBox,ECR_Block);
- }
- }
- World->LineTraceSingleByChannel(ConfirmHitResult, TraceStart, TraceEnd , ECC_HitBox);
- if (ConfirmHitResult.bBlockingHit)
- {
- if (ConfirmHitResult.Component.IsValid())
- {
- UBoxComponent* Box = Cast<UBoxComponent>(ConfirmHitResult.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};
- }
- 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::QueryAndPhysics);
- 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};
- }
- else // 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::QueryAndPhysics);
- 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, const FVector_NetQuantize& TraceStart, const TArray<FVector_NetQuantize>& HitLocations)
- {
- for (auto& Frame : FramePackages)
- {
- if (Frame.Character == nullptr) return FShotgunServerSideRewindResult();
- }
- FShotgunServerSideRewindResult ShotgunResult;
- TArray<FFramePackage> CurrentFrames;
- for (auto& Frame : FramePackages)
- {
- FFramePackage CurrentFrame;
- CurrentFrame.Character = Frame.Character;
- CacheBoxPositions(Frame.Character, CurrentFrame);
- MoveBoxes(Frame.Character, Frame);
- EnableCharacterMeshCollision(Frame.Character, ECollisionEnabled::NoCollision);
- CurrentFrames.Add(CurrentFrame);
- }
- for (auto& Frame : FramePackages)
- {
- // Enable Collision for the head first
- UBoxComponent* HeadBox = Frame.Character->HitCollisionBoxes[FName("head")];
- HeadBox->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
- HeadBox->SetCollisionResponseToChannel(ECC_HitBox, ECR_Block);
- }
- UWorld* World = GetWorld();
- // Check for Head shots
- for (auto& HitLocation : HitLocations)
- {
- FHitResult ConfirmHitResult;
- const FVector TraceEnd = TraceStart + (HitLocation - TraceStart) * 1.25f;
- if (World)
- {
- World->LineTraceSingleByChannel(
- ConfirmHitResult,
- TraceStart,
- TraceEnd,
- ECC_HitBox
- );
- ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(ConfirmHitResult.GetActor());
- if (BlasterCharacter)
- {
- if (ConfirmHitResult.Component.IsValid())
- {
- UBoxComponent* Box = Cast<UBoxComponent>(ConfirmHitResult.Component);
- if (Box)
- {
- DrawDebugBox(GetWorld(), Box->GetComponentLocation(), Box->GetScaledBoxExtent(), FQuat(Box->GetComponentRotation()), FColor::Red, false, 8.f);
- }
- }
- if (ShotgunResult.HeadShots.Contains(BlasterCharacter))
- {
- ShotgunResult.HeadShots[BlasterCharacter]++;
- }
- else
- {
- ShotgunResult.HeadShots.Emplace(BlasterCharacter, 1);
- }
- }
- }
- }
- // Enable collision for all boxes, then disable for head box
- for (auto& Frame : FramePackages)
- {
- for (auto& HitBoxPair : Frame.Character->HitCollisionBoxes)
- {
- if (HitBoxPair.Value != nullptr)
- {
- HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
- HitBoxPair.Value->SetCollisionResponseToChannel(ECC_HitBox,ECR_Block);
- }
- }
- UBoxComponent* HeadBox = Frame.Character->HitCollisionBoxes[FName("head")];
- HeadBox->SetCollisionEnabled(ECollisionEnabled::NoCollision);
- }
- // check for body shots
- for (auto& HitLocation : HitLocations)
- {
- FHitResult ConfirmHitResult;
- const FVector TraceEnd = TraceStart + (HitLocation - TraceStart) * 1.25f;
- if (World)
- {
- World->LineTraceSingleByChannel(
- ConfirmHitResult,
- TraceStart,
- TraceEnd,
- ECC_HitBox
- );
- ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(ConfirmHitResult.GetActor());
- if (BlasterCharacter)
- {
- if (ConfirmHitResult.Component.IsValid())
- {
- UBoxComponent* Box = Cast<UBoxComponent>(ConfirmHitResult.Component);
- if (Box)
- {
- DrawDebugBox(GetWorld(), Box->GetComponentLocation(), Box->GetScaledBoxExtent(), FQuat(Box->GetComponentRotation()), FColor::Blue, false, 8.f);
- }
- }
- if (ShotgunResult.BodyShots.Contains(BlasterCharacter))
- {
- ShotgunResult.BodyShots[BlasterCharacter]++;
- }
- else
- {
- ShotgunResult.BodyShots.Emplace(BlasterCharacter, 1);
- }
- }
- }
- }
- for (auto& Frame : CurrentFrames)
- {
- ResetHitBoxes(Frame.Character, Frame);
- EnableCharacterMeshCollision(Frame.Character, ECollisionEnabled::QueryAndPhysics);
- }
- return ShotgunResult;
- }
- void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage)
- {
- if (HitCharacter == nullptr) return;
- for(auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
- {
- if(HitBoxPair.Value != nullptr)
- {
- FBoxInformation BoxInfo;
- BoxInfo.Location = HitBoxPair.Value->GetComponentLocation();
- BoxInfo.Rotation = HitBoxPair.Value->GetComponentRotation();
- BoxInfo.BoxExtent = HitBoxPair.Value->GetScaledBoxExtent();
- OutFramePackage.HitBoxInfo.Add(HitBoxPair.Key, BoxInfo);
- }
- }
- }
- void ULagCompensationComponent::MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
- {
- if (HitCharacter == nullptr) return;
- for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
- {
- if (HitBoxPair.Value != nullptr)
- {
- const FBoxInformation* BoxValue = Package.HitBoxInfo.Find(HitBoxPair.Key);
- if (BoxValue)
- {
- HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
- HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
- HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtent);
- }
- }
- }
- }
- void ULagCompensationComponent::ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package)
- {
- if (HitCharacter == nullptr) return;
- for (auto& HitBoxPair : HitCharacter->HitCollisionBoxes)
- {
- if (HitBoxPair.Value != nullptr)
- {
- const FBoxInformation* BoxValue = Package.HitBoxInfo.Find(HitBoxPair.Key);
- if (BoxValue)
- {
- HitBoxPair.Value->SetWorldLocation(Package.HitBoxInfo[HitBoxPair.Key].Location);
- HitBoxPair.Value->SetWorldRotation(Package.HitBoxInfo[HitBoxPair.Key].Rotation);
- HitBoxPair.Value->SetBoxExtent(Package.HitBoxInfo[HitBoxPair.Key].BoxExtent);
- HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::NoCollision);
- }
- }
- }
- }
- void ULagCompensationComponent::EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter,
- ECollisionEnabled::Type CollisionEnabled)
- {
- if (HitCharacter && HitCharacter->GetMesh())
- {
- HitCharacter->GetMesh()->SetCollisionEnabled(CollisionEnabled);
- }
- }
- void ULagCompensationComponent::ShowFramePackage(const FFramePackage& Package, const FColor& Color)
- {
- for (auto& BoxInfo : Package.HitBoxInfo)
- {
- DrawDebugBox(
- GetWorld(),
- BoxInfo.Value.Location,
- BoxInfo.Value.BoxExtent,
- FQuat(BoxInfo.Value.Rotation),
- Color,
- false,
- 4.f
- );
- }
- }
- FServerSideRewindResult ULagCompensationComponent::ServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart,
- const FVector_NetQuantize& HitLocation, float HitTime)
- {
- FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime);
- return ConfirmHit(FrameToCheck, HitCharacter, TraceStart, HitLocation);
- }
- FServerSideRewindResult ULagCompensationComponent::ProjectileServerSideRewind(ABlasterCharacter* HitCharacter,
- const FVector_NetQuantize& TraceStart, const FVector_NetQuantize100& InitialVelocity, float HitTime)
- {
- FFramePackage FrameToCheck = GetFrameToCheck(HitCharacter, HitTime);
- return ProjectileConfirmHit(FrameToCheck, HitCharacter, TraceStart, InitialVelocity, HitTime);
- }
- 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 ShotgunConfirmHit(FramesToCheck, TraceStart, HitLocations);
- }
- FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitCharacter, float HitTime)
- {
- bool bReturn =
- HitCharacter == nullptr ||
- HitCharacter->GetLagCompensation() ||
- HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr ||
- HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr;
- if (bReturn) return FFramePackage();
- // Frame Package that we check to verify a hit
- FFramePackage FrameToCheck;
- bool bShouldInterpolate = true;
- // Frame History of the HitCharacter
- const TDoubleLinkedList<FFramePackage>& History = HitCharacter->GetLagCompensation()->FrameHistory;
- const float OldestHistoryTime = History.GetTail()->GetValue().Time;
- const float NewestHistoryTime = History.GetHead()->GetValue().Time;
- if (OldestHistoryTime > HitTime)
- {
- // Too far back - too laggy to do Server side rewind
- return FFramePackage();
- }
- if (OldestHistoryTime == HitTime)
- {
- FrameToCheck = History.GetTail()->GetValue();
- bShouldInterpolate = false;
- }
- if (NewestHistoryTime <= HitTime)
- {
- FrameToCheck = History.GetHead()->GetValue();
- bShouldInterpolate = false;
- }
- TDoubleLinkedList<FFramePackage>::TDoubleLinkedListNode* Younger = History.GetHead();
- TDoubleLinkedList<FFramePackage>::TDoubleLinkedListNode* Older = Younger;
- while (Older->GetValue().Time > HitTime) // is Older Still younger than HitTime?
- {
- // March back until: OlderTime < HitTime < YoungerTime
- if (Older->GetNextNode() == nullptr) break;
- Older = Older->GetNextNode();
- if (Older->GetValue().Time > HitTime)
- {
- Younger = Older;
- }
- }
- if (Older->GetValue().Time == HitTime) // Highly unlikely, but we found our frame to check
- {
- FrameToCheck = Older->GetValue();
- bShouldInterpolate = false;
- }
- if (bShouldInterpolate)
- {
- // Interpolate between Younger and Older
- FrameToCheck = InterpBetweenFrames(Older->GetValue(), Younger->GetValue(), HitTime);
- }
- FrameToCheck.Character = HitCharacter;
- return FrameToCheck;
- }
- void ULagCompensationComponent::ServerScoreRequest_Implementation(
- ABlasterCharacter* HitCharacter,const FVector_NetQuantize& TraceStart,
- const FVector_NetQuantize& HitLocation, float HitTime, AWeapon* DamageCauser)
- {
- FServerSideRewindResult Confirm = ServerSideRewind(HitCharacter, TraceStart, HitLocation, HitTime);
- if (Character && HitCharacter && DamageCauser && Confirm.bHitConfirmed)
- {
- UGameplayStatics::ApplyDamage(
- HitCharacter,
- DamageCauser->GetDamage(),
- Character->Controller,
- DamageCauser,
- UDamageType::StaticClass()
- );
- }
- }
- void ULagCompensationComponent::ProjectileServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter,
- const FVector_NetQuantize& TraceStart, const FVector_NetQuantize100& InitialVelocity, float HitTime)
- {
- FServerSideRewindResult Confirm = ProjectileServerSideRewind(HitCharacter, TraceStart, InitialVelocity, HitTime);
- if (Character && HitCharacter && Confirm.bHitConfirmed)
- {
- UGameplayStatics::ApplyDamage(
- HitCharacter,
- Character->GetEquippedWeapon()->GetDamage(),
- Character->Controller,
- Character->GetEquippedWeapon(),
- UDamageType::StaticClass()
- );
- }
- }
- void ULagCompensationComponent::ShotgunServerScoreRequest_Implementation(
- const TArray<ABlasterCharacter*>& HitCharacters, const FVector_NetQuantize& TraceStart,
- const TArray<FVector_NetQuantize>& HitLocations, float HitTime)
- {
- FShotgunServerSideRewindResult Confirm = ShotgunServerSideRewind(HitCharacters, TraceStart, HitLocations, HitTime);
- for (auto& HitCharacter : HitCharacters)
- {
- if (HitCharacter == nullptr || HitCharacter->GetEquippedWeapon() == nullptr || Character == nullptr) continue;
- float TotalDamage = 0.f;
- if (Confirm.HeadShots.Contains(HitCharacter))
- {
- float HeadShotDamage = Confirm.HeadShots[HitCharacter] * HitCharacter->GetEquippedWeapon()->GetDamage();
- TotalDamage += HeadShotDamage;
- }
- if (Confirm.BodyShots.Contains(HitCharacter))
- {
- float BodyShotDamage = Confirm.BodyShots[HitCharacter] * HitCharacter->GetEquippedWeapon()->GetDamage();
- TotalDamage += BodyShotDamage;
- }
- UGameplayStatics::ApplyDamage(
- HitCharacter,
- TotalDamage,
- Character->Controller,
- HitCharacter->GetEquippedWeapon(),
- UDamageType::StaticClass()
- );
- }
- }
- void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
- {
- Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
- 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);
- }
- }
- 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;
- BoxInformation.Location = BoxPair.Value->GetComponentLocation();
- BoxInformation.Rotation = BoxPair.Value->GetComponentRotation();
- BoxInformation.BoxExtent = BoxPair.Value->GetScaledBoxExtent();
- Package.HitBoxInfo.Add(BoxPair.Key, BoxInformation);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment