C++와 Unreal Engine으로 3D 게임 개발 4-3,4

UMG와 Animation
UMG에는 Animation 기능이 탑재되어있다. 다양한 연출을 쉽게~! bbb
- Animation 패널
- UMG 에디터 내에서 메뉴 상단에서 Window - Animations를 클릭하면 애니메이션을 다루는 창이 뜹니다.
- UMG 에디터 왼쪽 하단 (기본 레이아웃 기준)에 위치한 패널입니다.
- 여기서 새 애니메이션을 생성하거나, 이미 만든 애니메이션을 선택해 타임라인을 확인할 수 있습니다.
- Keyframe(키 프레임)
- 특정 시간대에 UI 속성(크기, 위치, 투명도, 색상 등)을 어떻게 바꿀지를 기록하는 지점입니다.
- 여러 개의 키 프레임을 연결하여 하나의 애니메이션 타임라인을 완성합니다.
Text 위젯 애니메이션 적용

이 텍스트가 게임 시작 시 바로 보이지 않도록, TextBlock의 Visibility를 Hidden으로 설정한다.
애니메이션 트랙 생성

에디터 왼쪽 하단의 Animation 패널에서 + Animation 버튼을 클릭해 새 애니메이션을 만든다.

아래쪽 타임라인 영역에서 Track을 추가할 수 있는데, 여기서 + Add 를 클릭하고 텍스트를 선택한다.
Keyframe (키 프레임) 설정

추가된 텍스트에서 옆에 희미하게 보이는 + 버튼을 누르면 추가할 수 있는 트랙들이 있다.
여기서 Render Opacity (투명도)를 트랙에 추가하여, 이 값이 시간에 따라 어떻게 변하는지 기록할 수 있도록 한다.

시간 바를 옮기면서 각각 Render Opacity 값을 변경하면 자동으로 트랙에 Key가 등록된다.
애니메이션을 Blueprint 재생 함수로 묶어두기
애니메이션 재생을 위해 C++에서 UMG 애니메이션 재생을 위한 블루프린트의 함수를 호출해야 한다.
이벤트 그래프에서 Function을 만든다.

시작 시 Visible 처리하고 Play Animation을 해준다.
📌 여기서 Num Loops to Play를 통해 반복 처리 가능!
- Num Loops
- 0 👉 무한 루프
- 1 👉 한 번
- 2 이상 👉 해당 횟수만큼
- Play Mode : Forward / Reverse / PingPong
if (bIsRestart)
{
UFunction* PlayAnimFunc = MainMenuWidgetInstance->FindFunction(FName("PlayGameOverAnim"));
if (PlayAnimFunc)
{
MainMenuWidgetInstance->ProcessEvent(PlayAnimFunc, nullptr);
}
if (UTextBlock* TotalScoreText = Cast<UTextBlock>(MainMenuWidgetInstance->GetWidgetFromName("TotalScoreText")))
{
if (USpartaGameInstance* SpartaGameInstance = Cast<USpartaGameInstance>(UGameplayStatics::GetGameInstance(this)))
{
TotalScoreText->SetText(FText::FromString(
FString::Printf(TEXT("Total Score: %d"), SpartaGameInstance->TotalScore)
));
}
}
}
WidgetComponent
- UMG (언리얼 모션 그래픽스)로 만든 위젯 (텍스트, 이미지, 버튼 등)을 3D 월드에 붙일 수 있게 해주는 컴포넌트이다.
- 예: “NPC 머리 위 체력바”, “아이템 위에 ‘F 키를 누르세요’ 텍스트” 등 가능.
- 언리얼 엔진에서 WidgetComponent를 사용하면, 2D로만 보이던 UI를 공간 내 특정 위치에 붙여 놓고, 카메라 각도에 따라 회전하거나 크기가 달라지는 모습을 만들 수 있다.
- WidgetComponent는 Actor에 부착(Attach)할 수 있는 컴포넌트이며, 특정 UUserWidget(UMG Blueprint 클래스)을 3D 상에 표시하게 해준다.
- 보통은 SetWidgetSpace(EWidgetSpace::World)로 설정하여, 월드 공간에 UI가 존재하게 함.
- 초기 상태에서 SetVisibility(false)로 해 두고, 플레이어가 가까이 왔을 때 SetVisibility(true)로 변경하여 표시 가능.
파티클 시스템 (Particla System)
👉 게임 내에서 불꽃, 연기, 폭발, 먼지 등 다양한 시각적 효과를 구현하기 위한 도구
- Cascade: 언리얼 엔진 3 시절부터 제공된 오래된 파티클 편집 툴이다. 언리얼 엔진 4, 5에서도 여전히 호환되지만, 신규 기능 업데이트는 주로 Niagara 위주로 이루어지고 있다.
- 초급자가 배우기에 상대적으로 간단하고 빠르게 결과를 볼 수 있음
- 레거시 프로젝트나 기존 아티스트 툴체인에서 많이 사용
- 복잡하거나 고급스러운 VFX 연출에는 한계
- Niagara: 언리얼 엔진 4 후반부터 새롭게 도입된 차세대 파티클 시스템이다. 언리얼 엔진 5에서는 Niagara가 공식적으로 권장되는 방식이다.
- 모듈 단위로 다양한 파티클 동작을 정교하게 제어 가능
- 블루프린트나 머티리얼, 스크립팅과 유기적으로 연동되어 고급 VFX를 쉽게 만들 수 있음
- GPU 파티클, 신규 기능 업데이트가 빠르게 적용
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item|Effects")
UParticleSystem* PickupParticle;
void ABaseItem::ActivateItem(AActor* Activator)
{
UParticleSystemComponent* Particle = nullptr;
if (PickupParticle)
{
Particle = UGameplayStatics::SpawnEmitterAtLocation(
GetWorld(),
PickupParticle,
GetActorLocation(),
GetActorRotation(),
true
);
}
if (Particle)
{
FTimerHandle DestroyParticleTimerHandle;
TWeakObjectPtr<UParticleSystemComponent> WeakParticle = Particle;
GetWorld()->GetTimerManager().SetTimer(
DestroyParticleTimerHandle,
[WeakParticle]()
{
if (WeakParticle.IsValid())
{
WeakParticle->DestroyComponent();
}
},
2.0f,
false
);
}
}

사운드 효과
- 사운드 웨이브(Sound Wave)
- 한 개의 오디오 파일(일반적으로 .wav)을 뜻한다.
- 게임에서 재생할 기본 오디오 데이터 그 자체라고 볼 수 있다.
- 단일 음원(싱글 트랙) 재생용으로 주로 사용된다.
- 엔진 내부적으로 Wave 탭 또는 사운드 웨이브 에셋으로 관리된다.
- 재생 시 별도의 추가 효과(랜덤 재생, 믹싱, 블렌딩 등)를 넣기 어렵고, 순수히 “오디오 파일”을 재생하기만 하는 형태다.
- 사운드 큐 (Sound Cue)
- 언리얼 엔진의 오디오 편집 그래프 시스템이다.
- 여러 개의 사운드 웨이브를 조합하거나, 랜덤/시퀀셜 재생, 믹싱, 페이드, 모듈레이션 등 다양한 처리를 시각적 노드 그래프로 설정할 수 있다.
- Sound Cue Editor라는 전용 편집 창에서 다양한 노드를 배치해 복잡한 사운드 로직을 구성할 수 있다.
- 사운드 에셋이 늘어나고, 상황에 따라 실시간으로 변화하는 사운드를 만들고 싶을 때 필수적이다.
- 배경음악의 구간 전환(Intro-Loop-Outro)이라든가, 발걸음 소리의 무작위 재생, 총격 사운드의 재생 피치 랜덤화 같은 동적 사운드에 활용된다.
- 사운드 웨이브 vs 사운드 큐, 언제 사용할까?
- 사운드 웨이브
- 단일 오디오 파일을 그대로 재생하는 경우.
- 간단한 UI 사운드, 짧은 효과음(단일 음원) 등에 적합.
- 사운드 큐
- 여러 사운드 웨이브를 조합하거나, 랜덤/페이드/모듈레이션 등 고급 기능을 적용해야 할 때.
- 같은 이벤트라도 여러 가지 소리를 번갈아 재생하거나, 재생 로직을 노드 그래프로 구성하고 싶을 때 사용.
- 사운드 웨이브
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Item|Effects")
USoundBase* PickupSound;
if (PickupSound)
{
UGameplayStatics::PlaySoundAtLocation(
GetWorld(),
PickupSound,
GetActorLocation()
);
}



TROUBLE
📌 UE C++ 타이머 + 람다 + UObject 수명 문제
지뢰 아이템으로 게임오버가 될 때 예외가 발생하며 실행이 중단 됐다.

👉 타이머가 실행될 시점엔 Particle이 유효하지 않음
TWeakObjectPtr 사용하고 람다식 안에서 유효성 체크
if (Particle)
{
FTimerHandle DestroyParticleHandle;
TWeakObjectPtr<UActorComponent> WeakParticle = Particle;
GetWorld()->GetTimerManager().SetTimer(
DestroyParticleHandle,
[WeakParticle]()
{
if (WeakParticle.IsValid())
{
WeakParticle->DestroyComponent();
}
},
2.0f,
false
);
}

팀플 전까지 할 것. 과제 8 끝내고 수학 공부
'내배캠Unreal_TIL > UE' 카테고리의 다른 글
| [TIL] 2026-01-29 | 아이템 스폰 이벤트, UI 디자인 (2) | 2026.01.29 |
|---|---|
| [TIL] 2026-01-28 | UE 게임 루프 및 UI 재설계 과제, 화면 뒤집기 (1) | 2026.01.28 |
| [TIL] 2026-01-26 | UE UI 위젯 설계 (1) | 2026.01.26 |
| [TIL] 2026-01-26 | Attribute System (0) | 2026.01.26 |
| [TIL] 2026-01-23 | 캐릭터 에셋 끄적거리기, 리깅이 안되어 있을 때 (4) | 2026.01.23 |