오늘 한 것
급정거 카메라 피드백, 브레이크 사운드, 엔진 사운드 구현했다.
급정거 카메라 무빙 - 델리게이트 + Timeline
구조
C++에서 델리게이트 선언 → BTT에서 브로드캐스트 → 블루프린트에서 Timeline으로 카메라 이동
C++ 추가
// CityVehiclePawn.h
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnEmergencyBrake, float, BrakeValue);
UPROPERTY(BlueprintAssignable, Category="Camera")
FOnEmergencyBrake OnEmergencyBrake;
UFUNCTION(BlueprintCallable, Category="Camera")
void TriggerEmergencyBrakeCamera(float BrakeValue);
bool bCameraTriggered = false;
// CityVehiclePawn.cpp
void ACityVehiclePawn::TriggerEmergencyBrakeCamera(float BrakeValue)
{
if (bCameraTriggered) return;
bCameraTriggered = true;
OnEmergencyBrake.Broadcast(BrakeValue);
}
// ResumeMovement에 추가
bCameraTriggered = false;
삽질 포인트
- BlueprintAssignable 델리게이트는 블루프린트에서 직접 브로드캐스트 불가
- 반드시 BlueprintCallable 함수로 감싸서 호출해야 함
- BTT는 매 프레임 실행되므로 bCameraTriggered 플래그로 한 번만 실행되게 해야 함
블루프린트 Timeline 설정
Break Moving Camera (Custom Event)
→ Timeline Play from Start
Update → SET BackSpringArm Target Arm Length = New Track 0
Timeline 커브 키값 (바운스 느낌):
0.0초 : 650 (시작)
0.3초 : 250 (확 쏠림)
1.2초 : 750 (살짝 튕김)
1.5초 : 650 (복귀)
Delay 노드는 함수 안에서 못 씀. 반드시 Custom Event 안에서 써야 함!
BTT 연결
Emergency Stop
→ Trigger Emergency Brake Camera (Target = As City Vehicle Pawn, Brake Value = 1.0)
→ Finish Execute
브레이크 사운드
C++ 구현
// CityVehiclePawn.h
UPROPERTY(EditAnywhere, Category="Sound")
TArray<TObjectPtr<USoundBase>> BrakeSounds;
// TriggerEmergencyBrakeCamera에 추가
if (BrakeSounds.Num() > 0)
{
int32 Index = FMath::RandRange(0, BrakeSounds.Num() - 1);
UGameplayStatics::PlaySoundAtLocation(this, BrakeSounds[Index], GetActorLocation());
}
- 배열로 여러 사운드 등록해서 랜덤 재생
- 블루프린트에서 Brake_1, Brake_2 배열에 추가
엔진 사운드 - RPM 피치 변화
C++ 구현
// CityVehiclePawn.h
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Sound")
TObjectPtr<UAudioComponent> EngineAudioComponent;
UPROPERTY(EditAnywhere, Category="Sound")
TObjectPtr<USoundBase> EngineSound;
// 생성자
EngineAudioComponent = CreateDefaultSubobject<UAudioComponent>(TEXT("EngineAudio"));
EngineAudioComponent->SetupAttachment(GetRootComponent());
EngineAudioComponent->bAutoActivate = false;
// BeginPlay
if (EngineSound)
{
EngineAudioComponent->SetSound(EngineSound);
EngineAudioComponent->Play();
}
// Tick - RPM에 따라 피치 조절
if (EngineAudioComponent && EngineAudioComponent->IsPlaying())
{
const float RPM = ChaosVehicleMovement->GetEngineRotationSpeed();
const float MaxRPM = 5500.0f;
const float PitchMin = 0.5f;
const float PitchMax = 2.0f;
const float Pitch = FMath::Lerp(PitchMin, PitchMax, RPM / MaxRPM);
EngineAudioComponent->SetPitchMultiplier(Pitch);
}
Sound Cue 설정
- Wave Player에서 Looping 체크
- Looping Wave Player → Output 구조
삽질 포인트
- 매 프레임 IsPlaying() 체크해서 꺼져있으면 Play() 다시 호출하면 루프가 끊겨서 뚝뚝 소리남
- 루프는 언리얼이 알아서 하도록 두고 ResumeMovement에서만 재시작하면 됨
- 엔진 루프 사운드는 seamless loop 파일이 아니면 루프 시 클릭 소리 발생 (완벽한 해결 어려움)
SplineFollower 조향 튜닝
지그재그 + 차선 이탈 해결
MaxYawDelta : 55 → 30 (조향 반응 강하게)
MaxYawDelta가 낮을수록 같은 각도 오차에서 더 강하게 조향 명령이 나와서 차선 이탈이 줄어든다
마무리
- BlueprintAssignable 델리게이트는 블루프린트에서 직접 브로드캐스트 불가 → BlueprintCallable 함수로 감싸야 함
- Timeline은 Custom Event 안에서만 사용 가능 (함수 안에서 Delay/Timeline 못 씀)
- 엔진 루프 사운드 뚝 끊김은 파일 자체가 seamless loop 아니면 해결 어려움
- BTT는 매 프레임 실행되므로 한 번만 실행해야 하는 로직은 플래그로 보호해야 함
'학습일지 > 언리얼' 카테고리의 다른 글
| UE5 패키징 & 로딩 스크린 (0) | 2026.05.27 |
|---|---|
| UE5 실시간 HUD 연동 & 로딩 화면 구현 TIL (0) | 2026.05.26 |
| 차량 AI 스플라인 추종 + 브레이크 등 + 헤드라이트 + 사이드미러 구현 (0) | 2026.05.18 |
| 언리얼 프레임워크 (0) | 2026.05.04 |
| Unreal - Pawn 클래스 과제 (0) | 2026.04.14 |