From f2e125969ec9ca942d2a09b8d616a39612e81c15 Mon Sep 17 00:00:00 2001 From: 997146918 <997146918@qq.com> Date: Fri, 25 Jul 2025 17:16:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=95=9C=E5=A4=B4=E7=9A=84?= =?UTF-8?q?=E6=9C=80=E5=B0=8F=E8=B7=9D=E7=A6=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Content/Gameplay/Ship/BP_Ship.uasset | Bin 53746 -> 34000 bytes ProjectFish/Content/Maps/Ship.umap | Bin 48072 -> 50008 bytes .../Components/ShipSpringArmComponent.cpp | 179 ++++++++++++++++++ .../Components/ShipSpringArmComponent.h | 31 +++ ProjectFish/Source/ProjectFish/Definations.h | 8 +- .../ProjectFish/Gameplay/Ship/Shipbase.cpp | 4 +- .../ProjectFish/Gameplay/Ship/Shipbase.h | 2 +- 7 files changed, 218 insertions(+), 6 deletions(-) create mode 100644 ProjectFish/Source/ProjectFish/Components/ShipSpringArmComponent.cpp create mode 100644 ProjectFish/Source/ProjectFish/Components/ShipSpringArmComponent.h diff --git a/ProjectFish/Content/Gameplay/Ship/BP_Ship.uasset b/ProjectFish/Content/Gameplay/Ship/BP_Ship.uasset index d0710bb914ce7a2ebff2b4beeb7ce93dead54431..c64103090f2db77b07b8bd7fecfc2713be9227dc 100644 GIT binary patch delta 10701 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 delta 1008 zcmYjPYe-a45I*<#3?C_OtZt@erY`E@V_oyTYU;X)B3_DwvUbuWdQhgC=p8-W#4w`=N!otdZq#i-9nn0AD^YAfvZx0emZLE(!?MWmM8D=JZ!>^J zD+Awj-fh%?YhY=Tf;pY1G9$cCH_;Iz{7sX=;S8QOR6D5Au#yo=FC2HK#>`kce}WP1 znLI77W0jCBo@(mZYHwDCEDF_4&H)Lrh=+&vq@JP~PN# z@nBYav!7W;szZ(BiaKb&HfX--(eTLb2}|k-s%mDPiX5KiwlFw^uzUmh=JM3m%2v$? z2hOlzmk{Q(u~kv2D=(HNm|0~ykEfr^&WdqwEWOq4OlL5C(Xp9wAK-p|3>~(x&b54= zuG$zh6(H|+` zRU~0YY(@c5L%d`khrqcpMw`u!2YZo$i-Z8}4H(y^xc|U6o2P?6+C1tZ71aAYrSR1d z?vbQON>wDQ1n;Vo6xn4~i7;55v=waCer{f<84YvIQh)Kq1)_(chobKkd|Fgg66bY3 z)ob*3L3er3r9<|&!{RVd+ZrLXo^sj3g~O5dVEneVE8(@Z*=-kAOJVM6Am}?2;fggG zUUd#}5h4rvJCos|tr04Ff`q89qh4^YFUUO-8$vknuam-J-wrUGO@`F|FPvNm9+;;= z)?SZ_Y4_TR2iF(;#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); + + // ... +} + diff --git a/ProjectFish/Source/ProjectFish/Components/ShipSpringArmComponent.h b/ProjectFish/Source/ProjectFish/Components/ShipSpringArmComponent.h new file mode 100644 index 0000000..1dac2a1 --- /dev/null +++ b/ProjectFish/Source/ProjectFish/Components/ShipSpringArmComponent.h @@ -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; +}; diff --git a/ProjectFish/Source/ProjectFish/Definations.h b/ProjectFish/Source/ProjectFish/Definations.h index 5a7875d..f0d9422 100644 --- a/ProjectFish/Source/ProjectFish/Definations.h +++ b/ProjectFish/Source/ProjectFish/Definations.h @@ -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; }; diff --git a/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.cpp b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.cpp index 49bc45f..8e94dd7 100644 --- a/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.cpp +++ b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.cpp @@ -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(TEXT("CameraBoom")); + CameraBoom = CreateDefaultSubobject(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; diff --git a/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.h b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.h index 7ed7209..7cdaf30 100644 --- a/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.h +++ b/ProjectFish/Source/ProjectFish/Gameplay/Ship/Shipbase.h @@ -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;