💭회고
🗺️마인드맵
📒학습 내용
1. 사운드 구현: 무기 재장전 및 엘리베이터 트리거
1.1 무기 재장전 사운드 구현
핵심 요약:
무기 타입에 따라 장전 사운드를 조건적으로 재생한다.
라이플과 피스톨일 때만 GunReloadCue가 활성화된다.
- 무기 타입 확인: EWeaponType Enum을 활용해 무기 종류를 구분한다.
- Enum (열거형): 무기 타입을 구분하는 태그 역할 (`EWeaponType`)
- 델리게이트: 상태 변화를 다른 시스템에 알리는 신호 (예: 무기 변경 시 UI 업데이트)
- Rifle과 Pistol일 때만 장전 사운드를 재생한다.
- Knife나 미장착 상태에서는 사운드가 재생되지 않도록 설정한다.
- 코드 구현: UCWeaponComponent의 Reload() 함수에 조건문을 추가하여, 무기가 라이플 또는 피스톨일 때만 사운드를 재생하도록 한다.
- 아래 코드는 C++에서 사운드 큐(GunReloadCue)를 재생하는 예시이다.
void UCWeaponComponent::Reload()
{
if (GetCurrentWeapon() == nullptr)
return; // 무기가 없으면 실행하지 않는다.
// 무기가 라이플 또는 피스톨일 때만 사운드 재생 조건을 충족한다.
if (Type == EWeaponType::Rifle || Type == EWeaponType::Pistol)
{
if (GunReloadCue)
{
UGameplayStatics::PlaySoundAtLocation(
GetWorld(),
GunReloadCue,
Owner->GetActorLocation(),
FRotator::ZeroRotator,
1.0f, // 볼륨 설정
1.0f, // 피치 설정
0.0f // 음량 감쇠 설정
);
}
GetCurrentWeapon()->Reload(); // 무기 재장전 로직을 실행한다.
}
else
{
UE_LOG(LogTemp, Log, TEXT("Cannot reload: Only Rifle or Pistol can reload."));
// 칼이나 무기 없음 상태에서는 재장전 로직을 실행하지 않는다.
}
}
1.2 블루프린트 구현 가이드
- 블루프린트 활용: C++ 대신 블루프린트에서 동일한 로직을 구현할 수 있다--한다.
- 절차:
- UCWeaponComponent의 Reload() 함수를 BlueprintCallable로 설정하여 블루프린트에서 호출 가능하도록 한다.
- 입력 이벤트(예, EnhancedInputAction IA_Reload)에서 무기 타입을 확인한 후, 라이플 또는 피스톨일 때 Play Sound at Location 노드를 사용해 재장전 사운드를 재생한다.
- 이후 Reload() 노드를 호출해 무기 재장전 로직을 실행한다.
2. 엘리베이터 트리거 구현
엘리베이터 트리거 구현은 게임의 레벨 전환 시, 사운드가 끊기지 않고 자연스럽게 진행되도록 하고 싶었다. 트리거 오버랩 시 사운드를 재생하고, 사운드 재생이 완료된 후 레벨 전환을 진행되게 하면 소리가 씹히지 않는다...!
2.1 문제 상황과 해결 방법 🐞
- 문제 상황: 단순히 트리거 오버랩 시 사운드를 재생하면, 레벨 전환으로 인해 사운드가 중간에 끊기는 문제가 발생한다.
- 해결 방법: 사운드의 재생 길이를 확인한 후, 해당 시간만큼 딜레이를 주고 레벨 전환을 실행한다.
- 주요 구현 포인트:
- 플레이어 캐릭터 확인 후 입력을 제한하여 혼란을 방지한다.
- ElevatorSound의 길이를 활용해 정확한 딜레이 타이머를 설정한다.
코드 : 아래 코드는 AAElevatorTrigger 클래스에서 트리거 오버랩 시 플레이어 캐릭터를 확인하고, 사운드 재생 후 레벨 전환을 딜레이와 함께 진행한다.
void AAElevatorTrigger::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex,
bool bFromSweep, const FHitResult& SweepResult)
{
// 내가 만든 플레이어 캐릭터인지 확인
ACPlayer* PlayerCharacter = Cast<ACPlayer>(OtherActor);
if (!PlayerCharacter) return;
if (ElevatorSound)
{
// 플레이어 입력 제한
PlayerCharacter->DisableInput(Cast<APlayerController>(PlayerCharacter->GetController()));
// ElevatorSound의 재생 길이 확인
float SoundDuration = ElevatorSound->GetDuration();
UGameplayStatics::PlaySound2D(this, ElevatorSound);
// 트리거 타입에 따라 다음 레벨 상태 설정
EGameState NewState = bIsN_Elevator ? EGameState::Labyrinth : EGameState::BossArea;
FTimerHandle TimerHandle;
GetWorld()->GetTimerManager().SetTimer(TimerHandle, [this, NewState]() {
LoadNextLevel(NewState);
}, SoundDuration, false);
}
}
🖥️ 레벨 전환 함수 :
void AAElevatorTrigger::LoadNextLevel(EGameState NewState)
{
ACGameState* GameState = GetWorld()->GetGameState<ACGameState>();
if (GameState)
{
if (bIsN_Elevator)
{
UE_LOG(LogTemp, Warning, TEXT("N엘리베이터 선택 → 연구소 미로 이동"));
GameState->SetGameState(EGameState::Labyrinth);
}
else
{
UE_LOG(LogTemp, Warning, TEXT("R엘리베이터 선택 → 보스 연구소 이동"));
GameState->SetGameState(EGameState::BossArea);
}
}
}
🟣오늘의 옵시디언 현황
'Dev. > UE 언리얼 엔진' 카테고리의 다른 글
[TIL_250228_1] 언리얼 엔진 파티클과 사운드로 몰입감 있는 게임 연출하기 (0) | 2025.02.28 |
---|---|
[TIL_250227] 언리얼 엔진 조명 설정, 애니메이션 블렌드, 오디오 Waveform Editor 정리 (0) | 2025.02.27 |
[TIL_250225] 언리얼 엔진으로 구현하는 표면 기반 발소리 & 3D 사운드 시스템 (0) | 2025.02.25 |
[TIL_250224] 언리얼 엔진 탄약 UI 연동, 크로스헤어(조준점) 줌인 구현 (0) | 2025.02.24 |
[TIL_250220] 언리얼 엔진 디졸브(Dissolve) 이펙트 가이드 (0) | 2025.02.20 |