UE5 Gameplay Camera 시스템
Spring Arm 고급 제어
섹션 제목: “Spring Arm 고급 제어”UCLASS()class AMyCharacter : public ACharacter { GENERATED_BODY()
UPROPERTY(VisibleAnywhere) USpringArmComponent* SpringArm; UPROPERTY(VisibleAnywhere) UCameraComponent* Camera;
public: AMyCharacter() { SpringArm = CreateDefaultSubobject<USpringArmComponent>("SpringArm"); SpringArm->SetupAttachment(RootComponent); SpringArm->TargetArmLength = 400.f; SpringArm->bUsePawnControlRotation = true; SpringArm->bEnableCameraLag = true; SpringArm->CameraLagSpeed = 10.f; SpringArm->bEnableCameraRotationLag = true; SpringArm->CameraRotationLagSpeed = 15.f;
Camera = CreateDefaultSubobject<UCameraComponent>("Camera"); Camera->SetupAttachment(SpringArm, USpringArmComponent::SocketName); }};
// 달릴 때 카메라 당기기void AMyCharacter::SetSprinting(bool bSprinting) { float TargetLength = bSprinting ? 600.f : 400.f; SpringArm->TargetArmLength = FMath::FInterpTo( SpringArm->TargetArmLength, TargetLength, DeltaTime, 5.f);}동적 FOV 조정
섹션 제목: “동적 FOV 조정”// 속도에 따른 FOV 변화 (속도감 연출)void AMyCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime);
float Speed = GetVelocity().Size(); float TargetFOV = FMath::Lerp(90.f, 100.f, Speed / MaxSpeed); float CurrentFOV = Camera->FieldOfView; Camera->FieldOfView = FMath::FInterpTo(CurrentFOV, TargetFOV, DeltaTime, 8.f);}카메라 셰이크
섹션 제목: “카메라 셰이크”// CameraShake 에셋 생성 (레거시)UCLASS()class UHitCameraShake : public ULegacyCameraShake { GENERATED_BODY() UHitCameraShake() { OscillationDuration = 0.3f; OscillationBlendInTime = 0.05f; OscillationBlendOutTime = 0.1f; RotOscillation.Pitch = { 3.f, 10.f, EWaveOscillatorClampingType::None }; RotOscillation.Yaw = { 2.f, 8.f, EWaveOscillatorClampingType::None }; }};
// 재생APlayerController* PC = GetWorld()->GetFirstPlayerController();PC->ClientStartCameraShake(UHitCameraShake::StaticClass(), 1.0f);
// 위치 기반 강도 (거리에 따라 약해짐)PC->ClientStartCameraShakeFromSource( UExplosionCameraShake::StaticClass(), ShakeSourceComponent);카메라 블렌딩 (CameraActor 전환)
섹션 제목: “카메라 블렌딩 (CameraActor 전환)”// 시네마틱 카메라로 블렌딩void AMyGameMode::SwitchToEventCamera(ACameraActor* EventCam, float BlendTime) { APlayerController* PC = GetWorld()->GetFirstPlayerController(); PC->SetViewTargetWithBlend(EventCam, BlendTime, VTBlend_Cubic);}
// 플레이어 카메라로 복귀void AMyGameMode::ReturnToPlayerCamera(float BlendTime) { APlayerController* PC = GetWorld()->GetFirstPlayerController(); PC->SetViewTargetWithBlend(PC->GetPawn(), BlendTime, VTBlend_EaseInOut, 2.f);}CameraModifier — 카메라 후처리
섹션 제목: “CameraModifier — 카메라 후처리”UCLASS()class USpeedLinesModifier : public UCameraModifier { GENERATED_BODY()
virtual bool ModifyCamera(float DeltaTime, FMinimalViewInfo& InOutPOV) override { ACharacter* Char = Cast<ACharacter>(GetViewTarget()); if (!Char) return false;
float Speed = Char->GetVelocity().Size(); float SpeedRatio = FMath::Clamp(Speed / 1000.f, 0.f, 1.f);
// FOV 살짝 증가 (속도감) InOutPOV.FOV += SpeedRatio * 5.f; return false; // 다른 Modifier도 처리 }};
// 컨트롤러에 추가PC->PlayerCameraManager->AddNewCameraModifier(USpeedLinesModifier::StaticClass());에임 어시스트 (부드러운 조준)
섹션 제목: “에임 어시스트 (부드러운 조준)”FRotator AMyPlayerController::GetAdjustedAimRotation(FRotator BaseRot) { // 조준 근처의 적 탐지 TArray<FHitResult> Hits; FVector Start = PlayerCameraManager->GetCameraLocation(); FVector End = Start + BaseRot.Vector() * 5000.f;
GetWorld()->SweepMultiByChannel(Hits, Start, End, FQuat::Identity, ECC_Pawn, FCollisionShape::MakeSphere(50.f));
for (const FHitResult& Hit : Hits) { if (AEnemy* Enemy = Cast<AEnemy>(Hit.GetActor())) { FRotator ToEnemy = UKismetMathLibrary::FindLookAtRotation( Start, Enemy->GetActorLocation()); // 5도 이내면 부드럽게 보정 if (FMath::Abs(FRotator::NormalizeAxis(BaseRot.Yaw - ToEnemy.Yaw)) < 5.f) return FMath::RInterpTo(BaseRot, ToEnemy, GetWorld()->DeltaTimeSeconds, 10.f); } } return BaseRot;}USpringArmComponentCameraLag/RotationLag로 자연스러운 카메라 추적- 속도에 따른 FOV/TargetArmLength 보간으로 속도감 연출
UCameraModifier로 카메라 파이프라인에 후처리 효과 주입SetViewTargetWithBlend로 이벤트 카메라 전환 시 부드러운 블렌딩- 카메라 셰이크는 거리 기반 소스 컴포넌트로 현실감 추가