Audio Component 활용
UAudioComponent를 활용한 사운드 재생 제어와 Blueprint/C++ 연동
UAudioComponent 기초
Actor에 사운드 소스를 부착하는 핵심 컴포넌트
UAudioComponent는 Actor에 부착되어 3D 공간에서 사운드를 재생하는 컴포넌트입니다. Sound Wave, Sound Cue, MetaSound Source 모두를 재생할 수 있으며, 위치/회전이 부모 Actor를 따라갑니다.
주요 프로퍼티
| 프로퍼티 | 타입 | 설명 |
|---|---|---|
| Sound | USoundBase* | 재생할 사운드 에셋 (Wave, Cue, MetaSound) |
| bAutoActivate | bool | Actor 스폰 시 자동 재생 여부 |
| bIsUISound | bool | UI 사운드 여부 (공간화 무시) |
| VolumeMultiplier | float | 볼륨 배수 (런타임 조절용) |
| PitchMultiplier | float | 피치 배수 (런타임 조절용) |
| AttenuationSettings | FSoundAttenuationSettings | 감쇠 설정 오버라이드 |
| ConcurrencySet | TSet<USoundConcurrency*> | 동시 재생 제한 설정 |
// Actor의 생성자에서 Audio Component 추가
AMyActor::AMyActor()
{
// Audio Component 생성 및 루트에 부착
AudioComp = CreateDefaultSubobject<UAudioComponent>(
TEXT("AudioComponent")
);
AudioComp->SetupAttachment(RootComponent);
// 기본 설정
AudioComp->bAutoActivate = false;
AudioComp->VolumeMultiplier = 1.0f;
// Sound 에셋 지정 (에디터에서도 설정 가능)
static ConstructorHelpers::FObjectFinder<USoundBase>
SoundFinder(TEXT("/Game/Audio/SFX/MS_EngineLoop"));
if (SoundFinder.Succeeded())
{
AudioComp->SetSound(SoundFinder.Object);
}
}
재생 제어 API
Play, Stop, Fade 등 런타임 재생 제어 함수
핵심 재생 함수
| 함수 | 설명 | Blueprint 노출 |
|---|---|---|
Play(float StartTime) |
지정 시간부터 재생 시작 | O |
Stop() |
즉시 정지 | O |
FadeIn(float Duration, float Volume, float StartTime) |
지정 시간에 걸쳐 페이드 인 | O |
FadeOut(float Duration, float Volume) |
지정 시간에 걸쳐 페이드 아웃 후 정지 | O |
SetPaused(bool bPause) |
일시정지/재개 | O |
AdjustVolume(float Duration, float Target) |
지정 시간에 걸쳐 볼륨 조절 | O |
SetPitchMultiplier(float NewPitch) |
피치 배수 변경 | O |
IsPlaying() |
현재 재생 중인지 확인 | O |
// 엔진 시동 - 페이드 인으로 자연스러운 시작
void AVehicle::StartEngine()
{
if (EngineAudioComp && !EngineAudioComp->IsPlaying())
{
// 2초에 걸쳐 볼륨 1.0까지 페이드 인
EngineAudioComp->FadeIn(2.0f, 1.0f);
}
}
// 엔진 정지 - 페이드 아웃
void AVehicle::StopEngine()
{
if (EngineAudioComp && EngineAudioComp->IsPlaying())
{
// 1.5초에 걸쳐 페이드 아웃 (볼륨 0까지)
EngineAudioComp->FadeOut(1.5f, 0.0f);
}
}
// RPM에 따른 피치 변경
void AVehicle::UpdateEnginePitch(float RPM)
{
// RPM 0~7000을 피치 0.5~2.0으로 매핑
float PitchValue = FMath::GetMappedRangeValueClamped(
FVector2D(0.f, 7000.f),
FVector2D(0.5f, 2.0f),
RPM
);
EngineAudioComp->SetPitchMultiplier(PitchValue);
}
이벤트와 델리게이트
오디오 재생 완료, 마커 등의 이벤트 처리
UAudioComponent는 다양한 델리게이트를 제공하여 사운드 재생 상태 변화에 대응할 수 있습니다.
주요 델리게이트
| 델리게이트 | 발생 시점 | 활용 예시 |
|---|---|---|
OnAudioFinished |
사운드 재생 완료 시 | 재생 완료 후 다음 트랙 재생 |
OnAudioPlaybackPercent |
재생 진행률 업데이트 시 | 진행률 UI 표시 |
OnAudioMultiEnvelopeValue |
엔벨로프 값 변경 시 | 사운드 시각화, VU 미터 |
// 재생 완료 델리게이트 바인딩
void AMusicPlayer::PlayTrack(USoundBase* Track)
{
MusicAudioComp->SetSound(Track);
MusicAudioComp->Play();
// 재생 완료 시 OnTrackFinished 호출
MusicAudioComp->OnAudioFinished.AddDynamic(
this, &AMusicPlayer::OnTrackFinished
);
}
void AMusicPlayer::OnTrackFinished()
{
// 다음 트랙으로 넘어가기
CurrentTrackIndex = (CurrentTrackIndex + 1) % Playlist.Num();
PlayTrack(Playlist[CurrentTrackIndex]);
}
// 재생 진행률 추적
MusicAudioComp->OnAudioPlaybackPercent.AddDynamic(
this, &AMusicPlayer::OnPlaybackProgress
);
void AMusicPlayer::OnPlaybackProgress(
const USoundWave* PlayingSoundWave,
const float PlaybackPercent)
{
// 0.0 ~ 1.0 사이의 진행률
ProgressBar->SetPercent(PlaybackPercent);
}
Blueprint에서는 Audio Component의 On Audio Finished 이벤트 노드를 바인딩하거나, Assign On Audio Finished 함수를 사용하여 동일한 기능을 구현할 수 있습니다. 이벤트 디스패처처럼 동작합니다.
Spawn Sound 함수 패밀리
UGameplayStatics의 다양한 사운드 재생 함수 비교
UAudioComponent 외에도 UGameplayStatics가 제공하는 간편 함수로 사운드를 재생할 수 있습니다. 상황에 맞는 함수를 선택하는 것이 중요합니다.
| 함수 | 공간화 | 반환값 | 적합한 용도 |
|---|---|---|---|
PlaySound2D |
X (2D) | void | UI 사운드, 전역 알림 |
PlaySoundAtLocation |
O (고정 위치) | void | 일회성 효과음 (폭발, 충격) |
SpawnSound2D |
X (2D) | UAudioComponent* | 제어가 필요한 2D 사운드 |
SpawnSoundAtLocation |
O (고정 위치) | UAudioComponent* | 제어가 필요한 위치 고정 사운드 |
SpawnSoundAttached |
O (부착, 이동) | UAudioComponent* | 이동하는 오브젝트에 부착 (차량 등) |
PlaySound2D와 PlaySoundAtLocation은 "발사 후 잊기(Fire-and-Forget)" 패턴입니다. 재생 시작 후 제어할 수 없으므로, 재생 중 볼륨 변경/정지/페이드가 필요한 경우 반드시 Spawn 계열 함수를 사용하세요.
// 1. UI 클릭 사운드 (일회성, 2D)
UGameplayStatics::PlaySound2D(this, ClickSound);
// 2. 폭발 사운드 (일회성, 위치 고정)
UGameplayStatics::PlaySoundAtLocation(
this, ExplosionSound, ExplosionLocation);
// 3. 루프 사운드 (제어 필요, 위치 이동)
UAudioComponent* LoopComp =
UGameplayStatics::SpawnSoundAttached(
EngineLoopSound,
VehicleMesh, // 부착 대상
NAME_None, // 소켓 이름
FVector::ZeroVector, // 상대 위치
FRotator::ZeroRotator,
EAttachLocation::KeepRelativeOffset,
true // 자동 재생
);
// 이후 LoopComp를 통해 볼륨/피치 제어 가능
LoopComp->SetVolumeMultiplier(0.8f);
LoopComp->SetPitchMultiplier(1.2f);
핵심 요약
- UAudioComponent는 Actor에 부착되어 3D 사운드를 재생하는 핵심 컴포넌트이다
- Play/Stop/FadeIn/FadeOut 등의 함수로 런타임 재생을 제어할 수 있다
- OnAudioFinished 델리게이트로 재생 완료 이벤트를 처리할 수 있다
- "발사 후 잊기"에는 PlaySoundAtLocation, 제어가 필요하면 SpawnSoundAttached를 사용한다
- 이동하는 오브젝트의 사운드는 반드시 SpawnSoundAttached로 부착해야 위치가 자동 업데이트된다
도전 과제
배운 내용을 직접 실습해보세요
블루프린트에서 UAudioComponent를 Actor에 추가하고, Play, Stop, FadeIn, FadeOut, AdjustVolume 함수를 호출하는 로직을 구현하세요. 트리거 볼륨 진입/이탈 시 배경음이 페이드인/아웃되는 시스템을 만드세요.
UGameplayStatics::PlaySoundAtLocation(), SpawnSoundAtLocation(), PlaySound2D(), SpawnSound2D()의 차이를 실험하세요. Fire-and-forget 방식과 컴포넌트 반환 방식의 장단점을 정리하고, 각각 적합한 사용 사례를 문서화하세요.
동시에 재생 가능한 사운드 수를 관리하는 오디오 컴포넌트 매니저를 구현하세요. 우선순위 기반 Voice 관리, 거리 기반 컬링, 자동 풀링을 포함하여 대량의 사운드 소스가 있는 환경에서도 안정적으로 동작하는 시스템을 만드세요.