1. 문제 상황
적이 죽어서 사망 어빌리티(UGA_EnemyDeath)가 실행되었음에도, 3초간의 렉돌 대기 시간 동안 플레이어가 적을 공격하면 피격 사운드가 계속 중복으로 재생됨.
2. 원인 분석
- 캡슐만 제거: Enemy->GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);으로 캡슐은 껐지만, Mesh의 콜리전이 살아있어 물리적 타격이 계속 들어옴.
- 상태 체크 미흡: 사망 어빌리티가 이미 실행 중인데도 다른 피격 로직이 IsDead 상태를 확인하지 않고 사운드를 재생함.
3. 해결 과정 및 코드 조각
[A] 중복 실행 방지 (Check & Set) 어빌리티 시작 시점에 게터(IsDead())로 확인하고 즉시 상태를 고정하여, 0.1초 사이에 들어오는 추가 호출을 차단했습니다.
C++
if (Enemy)
{
// [추가] 이미 죽은 상태라면 중복 실행하지 않음
if (Enemy->IsDead())
{
EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
return;
}
PlayRandomDeathSound(Enemy); // 사운드 재생
Enemy->SetIsDead(true); // 즉시 사망 상태로 변경
// ... 후속 로직
}
[B] 물리적 판정 완전 제거 (Ignore All) 캡슐뿐만 아니라 메시의 콜리전까지 응답 채널을 모두 Ignore로 설정하여 투명 인간 상태로 만들었습니다.
C++
// 캡슐 콜리전 제거
Enemy->GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Enemy->GetCapsuleComponent()->SetResponseToAllChannels(ECR_Ignore); // 모든 채널 무시
// [추가] 메시 콜리전도 꺼야 추가 피격 판정을 막음
Enemy->GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Enemy->GetMesh()->SetResponseToAllChannels(ECR_Ignore);
[C] 비동기 종료 보장 (Timer & EndAbility) 타이머가 끝난 뒤 어빌리티를 종료하도록 위치를 옮겨, 3초 동안 AbilityPtr이 유효하게 유지되도록 했습니다.
C++
GetWorld()->GetTimerManager().SetTimer(RagdollTimerHandle, [WeakThis, WeakEnemy]()
{
// ... 렉돌 및 아이템 드랍 로직 ...
// [변경] 모든 로직이 끝난 후 내부 정보를 이용해 안전하게 종료
if (AbilityPtr)
{
AbilityPtr->K2_EndAbility();
}
}, RagdollDelay, false);
4. 결과
위 조치를 통해 적이 죽는 순간 모든 공격이 적을 통과하게 되었으며, IsDead 플래그 체크를 통해 사망 사운드가 단 한 번만 출력되도록 수정 완료했습니다.
'내배캠 TIL' 카테고리의 다른 글
| [내배캠 TIL 260309] C++ 대칭 문자열 생성 (0) | 2026.03.09 |
|---|---|
| [내배캠 TIL 260305] CH.3 조별 과제 KPT회고 (0) | 2026.03.05 |
| [내배캠 TIL 260224] C++ std::sort 커스텀 비교 함수 구현하기 (0) | 2026.02.24 |
| [내배캠 TIL 260211] Unreal GAS 기반 Enemy AI 시스템 설계 (0) | 2026.02.11 |
| [내배캠 TIL 260209] Unity 모델 에셋의 Unreal Engine 이식 및 좌표계 트러블슈팅 (0) | 2026.02.09 |