-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #35 from xthebat/30-add-camera-vertical-lag
Added damper for vertical camera movement
- Loading branch information
Showing
8 changed files
with
233 additions
and
20 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
// Copyright Epic Games, Inc. All Rights Reserved. | ||
|
||
#pragma once | ||
|
||
#include "CoreMinimal.h" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 147 additions & 0 deletions
147
Source/Cloud9/Character/Components/Cloud9SpringArmComponent.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
#include "Cloud9SpringArmComponent.h" | ||
|
||
#include "Cloud9/Tools/Cloud9ToolsLibrary.h" | ||
|
||
|
||
UCloud9SpringArmComponent::UCloud9SpringArmComponent() | ||
{ | ||
CameraLagVector = FVector::OneVector; | ||
} | ||
|
||
void UCloud9SpringArmComponent::UpdateDesiredArmLocation( | ||
bool bDoTrace, | ||
bool bDoLocationLag, | ||
bool bDoRotationLag, | ||
float DeltaTime) | ||
{ | ||
FRotator DesiredRot = GetTargetRotation(); | ||
|
||
// Apply 'lag' to rotation if desired | ||
if (bDoRotationLag) | ||
{ | ||
if (bUseCameraLagSubstepping && DeltaTime > CameraLagMaxTimeStep && CameraRotationLagSpeed > 0.f) | ||
{ | ||
const FRotator ArmRotStep = (DesiredRot - PreviousDesiredRot).GetNormalized() * (1.f / DeltaTime); | ||
FRotator LerpTarget = PreviousDesiredRot; | ||
float RemainingTime = DeltaTime; | ||
while (RemainingTime > KINDA_SMALL_NUMBER) | ||
{ | ||
const float LerpAmount = FMath::Min(CameraLagMaxTimeStep, RemainingTime); | ||
LerpTarget += ArmRotStep * LerpAmount; | ||
RemainingTime -= LerpAmount; | ||
|
||
DesiredRot = FRotator( | ||
FMath::QInterpTo( | ||
FQuat(PreviousDesiredRot), | ||
FQuat(LerpTarget), | ||
LerpAmount, | ||
CameraRotationLagSpeed) | ||
); | ||
|
||
PreviousDesiredRot = DesiredRot; | ||
} | ||
} | ||
else | ||
{ | ||
DesiredRot = FRotator( | ||
FMath::QInterpTo( | ||
FQuat(PreviousDesiredRot), | ||
FQuat(DesiredRot), | ||
DeltaTime, | ||
CameraRotationLagSpeed | ||
) | ||
); | ||
} | ||
} | ||
PreviousDesiredRot = DesiredRot; | ||
|
||
// Get the spring arm 'origin', the target we want to look at | ||
FVector ArmOrigin = GetComponentLocation() + TargetOffset; | ||
// We lag the target, not the actual camera position, so rotating the camera around does not have lag | ||
FVector DesiredLoc = ArmOrigin; | ||
if (bDoLocationLag) | ||
{ | ||
const auto LocationLag = CameraLagSpeed * CameraLagVector; | ||
|
||
if (bUseCameraLagSubstepping | ||
&& DeltaTime > CameraLagMaxTimeStep | ||
&& LocationLag != FVector::ZeroVector) | ||
{ | ||
const FVector ArmMovementStep = (DesiredLoc - PreviousDesiredLoc) * (1.f / DeltaTime); | ||
auto LerpTarget = PreviousDesiredLoc; | ||
|
||
float RemainingTime = DeltaTime; | ||
while (RemainingTime > KINDA_SMALL_NUMBER) | ||
{ | ||
const float LerpAmount = FMath::Min(CameraLagMaxTimeStep, RemainingTime); | ||
LerpTarget += ArmMovementStep * LerpAmount; | ||
RemainingTime -= LerpAmount; | ||
|
||
DesiredLoc = UCloud9ToolsLibrary::VInterpTo(PreviousDesiredLoc, LerpTarget, LerpAmount, LocationLag); | ||
PreviousDesiredLoc = DesiredLoc; | ||
} | ||
} | ||
else | ||
{ | ||
DesiredLoc = UCloud9ToolsLibrary::VInterpTo(PreviousDesiredLoc, DesiredLoc, DeltaTime, LocationLag); | ||
} | ||
|
||
if (const auto FromOrigin = DesiredLoc - ArmOrigin; | ||
CameraLagMaxDistance > 0.f && FromOrigin.SizeSquared() > FMath::Square(CameraLagMaxDistance)) | ||
{ | ||
DesiredLoc = ArmOrigin + FromOrigin.GetClampedToMaxSize(CameraLagMaxDistance); | ||
} | ||
} | ||
|
||
PreviousArmOrigin = ArmOrigin; | ||
PreviousDesiredLoc = DesiredLoc; | ||
|
||
// Now offset camera position back along our rotation | ||
DesiredLoc -= DesiredRot.Vector() * TargetArmLength; | ||
// Add socket offset in local space | ||
DesiredLoc += FRotationMatrix(DesiredRot).TransformVector(SocketOffset); | ||
|
||
// Do a sweep to ensure we are not penetrating the world | ||
FVector ResultLoc; | ||
if (bDoTrace && TargetArmLength != 0.0f) | ||
{ | ||
bIsCameraFixed = true; | ||
FCollisionQueryParams QueryParams(SCENE_QUERY_STAT(SpringArm), false, GetOwner()); | ||
|
||
FHitResult Result; | ||
GetWorld()->SweepSingleByChannel( | ||
Result, | ||
ArmOrigin, | ||
DesiredLoc, | ||
FQuat::Identity, | ||
ProbeChannel, | ||
FCollisionShape::MakeSphere(ProbeSize), | ||
QueryParams); | ||
|
||
UnfixedCameraPosition = DesiredLoc; | ||
|
||
ResultLoc = BlendLocations(DesiredLoc, Result.Location, Result.bBlockingHit, DeltaTime); | ||
|
||
if (ResultLoc == DesiredLoc) | ||
{ | ||
bIsCameraFixed = false; | ||
} | ||
} | ||
else | ||
{ | ||
ResultLoc = DesiredLoc; | ||
bIsCameraFixed = false; | ||
UnfixedCameraPosition = ResultLoc; | ||
} | ||
|
||
// Form a transform for new world transform for camera | ||
FTransform WorldCamTM(DesiredRot, ResultLoc); | ||
// Convert to relative to component | ||
FTransform RelCamTM = WorldCamTM.GetRelativeTransform(GetComponentTransform()); | ||
|
||
// Update socket location/rotation | ||
RelativeSocketLocation = RelCamTM.GetLocation(); | ||
RelativeSocketRotation = RelCamTM.GetRotation(); | ||
|
||
UpdateChildTransforms(); | ||
} |
32 changes: 32 additions & 0 deletions
32
Source/Cloud9/Character/Components/Cloud9SpringArmComponent.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#pragma once | ||
|
||
#include "CoreMinimal.h" | ||
#include "GameFramework/SpringArmComponent.h" | ||
#include "Cloud9SpringArmComponent.generated.h" | ||
|
||
|
||
UCLASS(ClassGroup=(Camera), meta=(BlueprintSpawnableComponent)) | ||
class CLOUD9_API UCloud9SpringArmComponent : public USpringArmComponent | ||
{ | ||
GENERATED_BODY() | ||
|
||
public: | ||
// TODO: CameraLagRotator | ||
|
||
/** | ||
* If bEnableCameraLag is true, controls how quickly camera reaches target position by each axis. | ||
* Values of this vector multiplies with @CameraLagSpeed. | ||
*/ | ||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Lag, meta=(editcondition="bEnableCameraLag")) | ||
FVector CameraLagVector; | ||
|
||
public: | ||
UCloud9SpringArmComponent(); | ||
|
||
virtual void UpdateDesiredArmLocation( | ||
bool bDoTrace, | ||
bool bDoLocationLag, | ||
bool bDoRotationLag, | ||
float DeltaTime | ||
) override; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters