添加镜头的最小距离
This commit is contained in:
parent
2ec5f3df07
commit
f2e125969e
Binary file not shown.
Binary file not shown.
@ -0,0 +1,179 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "ShipSpringArmComponent.h"
|
||||
|
||||
#include "PhysicsEngine/PhysicsSettings.h"
|
||||
|
||||
|
||||
// Sets default values for this component's properties
|
||||
UShipSpringArmComponent::UShipSpringArmComponent()
|
||||
{
|
||||
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
|
||||
// off to improve performance if you don't need them.
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
// Called when the game starts
|
||||
void UShipSpringArmComponent::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
// ...
|
||||
|
||||
}
|
||||
|
||||
void UShipSpringArmComponent::UpdateDesiredArmLocation(bool bDoTrace, bool bDoLocationLag, bool bDoRotationLag,
|
||||
float DeltaTime)
|
||||
{
|
||||
FRotator DesiredRot = GetTargetRotation();
|
||||
|
||||
// If our viewtarget is simulating using physics, we may need to clamp deltatime
|
||||
if (bClampToMaxPhysicsDeltaTime)
|
||||
{
|
||||
// Use the same max timestep cap as the physics system to avoid camera jitter when the viewtarget simulates less time than the camera
|
||||
DeltaTime = FMath::Min(DeltaTime, UPhysicsSettings::Get()->MaxPhysicsDeltaTime);
|
||||
}
|
||||
|
||||
// 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 > UE_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)
|
||||
{
|
||||
if (bUseCameraLagSubstepping && DeltaTime > CameraLagMaxTimeStep && CameraLagSpeed > 0.f)
|
||||
{
|
||||
const FVector ArmMovementStep = (DesiredLoc - PreviousDesiredLoc) * (1.f / DeltaTime);
|
||||
FVector LerpTarget = PreviousDesiredLoc;
|
||||
|
||||
float RemainingTime = DeltaTime;
|
||||
while (RemainingTime > UE_KINDA_SMALL_NUMBER)
|
||||
{
|
||||
const float LerpAmount = FMath::Min(CameraLagMaxTimeStep, RemainingTime);
|
||||
LerpTarget += ArmMovementStep * LerpAmount;
|
||||
RemainingTime -= LerpAmount;
|
||||
|
||||
DesiredLoc = FMath::VInterpTo(PreviousDesiredLoc, LerpTarget, LerpAmount, CameraLagSpeed);
|
||||
PreviousDesiredLoc = DesiredLoc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DesiredLoc = FMath::VInterpTo(PreviousDesiredLoc, DesiredLoc, DeltaTime, CameraLagSpeed);
|
||||
}
|
||||
|
||||
// Clamp distance if requested
|
||||
bool bClampedDist = false;
|
||||
if (CameraLagMaxDistance > 0.f)
|
||||
{
|
||||
const FVector FromOrigin = DesiredLoc - ArmOrigin;
|
||||
if (FromOrigin.SizeSquared() > FMath::Square(CameraLagMaxDistance))
|
||||
{
|
||||
DesiredLoc = ArmOrigin + FromOrigin.GetClampedToMaxSize(CameraLagMaxDistance);
|
||||
bClampedDist = true;
|
||||
}
|
||||
}
|
||||
|
||||
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
|
||||
if (bDrawDebugLagMarkers)
|
||||
{
|
||||
DrawDebugSphere(GetWorld(), ArmOrigin, 5.f, 8, FColor::Green);
|
||||
DrawDebugSphere(GetWorld(), DesiredLoc, 5.f, 8, FColor::Yellow);
|
||||
|
||||
const FVector ToOrigin = ArmOrigin - DesiredLoc;
|
||||
DrawDebugDirectionalArrow(GetWorld(), DesiredLoc, DesiredLoc + ToOrigin * 0.5f, 7.5f, bClampedDist ? FColor::Red : FColor::Green);
|
||||
DrawDebugDirectionalArrow(GetWorld(), DesiredLoc + ToOrigin * 0.5f, ArmOrigin, 7.5f, bClampedDist ? FColor::Red : FColor::Green);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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;
|
||||
//设置机械臂的最小镜头距离
|
||||
if (FVector::Dist(ArmOrigin, Result.Location) > MinArmLength)
|
||||
ResultLoc = BlendLocations(DesiredLoc, Result.Location, Result.bBlockingHit, DeltaTime);
|
||||
else
|
||||
{
|
||||
ResultLoc = DesiredLoc;
|
||||
}
|
||||
|
||||
//FVector::Dist(ArmOrigin, tempResult) > MinArmLength
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
// Called every frame
|
||||
void UShipSpringArmComponent::TickComponent(float DeltaTime, ELevelTick TickType,
|
||||
FActorComponentTickFunction* ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/SpringArmComponent.h"
|
||||
#include "ShipSpringArmComponent.generated.h"
|
||||
|
||||
|
||||
UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent))
|
||||
class PROJECTFISH_API UShipSpringArmComponent : public USpringArmComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this component's properties
|
||||
UShipSpringArmComponent();
|
||||
|
||||
protected:
|
||||
// Called when the game starts
|
||||
virtual void BeginPlay() override;
|
||||
virtual void UpdateDesiredArmLocation(bool bDoTrace, bool bDoLocationLag, bool bDoRotationLag, float DeltaTime);
|
||||
public:
|
||||
// Called every frame
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
|
||||
FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
public:
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
float MinArmLength = 200.f;
|
||||
};
|
||||
@ -243,7 +243,7 @@ struct FShipDataConfig
|
||||
|
||||
/*** Camera ***/
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Position", meta = (ForceUnits = "cm", ToolTip = "与角色距离"))
|
||||
float CameraDistance = 800.0f;
|
||||
float CameraDistance = 1200.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Position", meta = (ForceUnits = "cm", ToolTip = "与角色高度差"))
|
||||
float CameraHeightOffset = 600.0f;
|
||||
@ -266,9 +266,9 @@ struct FShipDataConfig
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Follow", meta = (ToolTip = "镜头跟随阻尼"))
|
||||
float CameraFollowLagRatio = 3.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Collision", meta = (ToolTip = "镜头跟随阻尼"))
|
||||
float CameraCollisionLagRatio = 3.0f;
|
||||
// UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Collision", meta = (ToolTip = "镜头跟随阻尼"))
|
||||
// float CameraCollisionLagRatio = 3.0f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Collision", meta = (ForceUnits = "cm", ToolTip = "与角色的最小距离"))
|
||||
float CameraMinDistance = 200.0f;
|
||||
float CameraMinDistance = 500.0f;
|
||||
};
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "Components/CapsuleComponent.h"
|
||||
#include "GameFramework/CharacterMovementComponent.h"
|
||||
#include "GameFramework/SpringArmComponent.h"
|
||||
#include "ProjectFish/Components/ShipSpringArmComponent.h"
|
||||
|
||||
|
||||
class UEnhancedInputLocalPlayerSubsystem;
|
||||
@ -41,7 +42,7 @@ AShipbase::AShipbase()
|
||||
ShipMesh->OnComponentBeginOverlap.AddDynamic(this, &AShipbase::OnOverlapWall);
|
||||
ShipMesh->SetupAttachment(RootComponent);
|
||||
//camera arm
|
||||
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
|
||||
CameraBoom = CreateDefaultSubobject<UShipSpringArmComponent>(TEXT("CameraBoom"));
|
||||
CameraBoom->SetupAttachment(RootComponent);
|
||||
CameraBoom->TargetArmLength = 400.0f; // The camera follows at this distance behind the character
|
||||
CameraBoom->bUsePawnControlRotation = true; // Rotate the arm based on the controller
|
||||
@ -195,6 +196,7 @@ void AShipbase::ApplyCameraSettings()
|
||||
{
|
||||
CameraBoom->TargetArmLength = ShipData.CameraDistance;
|
||||
CameraBoom->SocketOffset = FVector(0, 0, ShipData.CameraHeightOffset);
|
||||
CameraBoom->MinArmLength = ShipData.CameraMinDistance;
|
||||
FollowCamera->SetRelativeRotation(FRotator(ShipData.CameraGroundAngle, 0, 0));
|
||||
|
||||
CameraBoom->bEnableCameraLag = true;
|
||||
|
||||
@ -61,7 +61,7 @@ protected:
|
||||
|
||||
/***Camera***/
|
||||
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = Camera, meta = ( AllowPrivateAccess = "true"))
|
||||
class USpringArmComponent* CameraBoom;
|
||||
class UShipSpringArmComponent* CameraBoom;
|
||||
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = Camera, meta = ( AllowPrivateAccess = "true"))
|
||||
class UCameraComponent* FollowCamera;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user