[CH4-14] 스피드 부스트 효과 지속성 문제 해결

김여울·2025년 9월 29일
0

내일배움캠프

목록 보기
86/111

💥 문제 상황

스피드 부스트 아이템을 사용한 후 슬라이딩이나 수영을 하면 부스트 효과가 사라지고 기본 속도로 되돌아가는 문제가 발생했다.

🔍 원인 분석

  1. OnRepIsSliding() 함수에서 슬라이딩 종료 시 MaxWalkSpeed 를 하드코딩된 기본값(400)으로 강제 설정

  2. 수영 모드에서 걷기 모드로 전환될 때도 유사한 문제 발생

  3. CharacterMovementComponent 가 Movement Mode 변경 시 속도를 초기화하는 것이 원인

🔧 해결 방안

1. SpeedBoostEffectComponent 개선

// 새로운 함수들 추가 (public 섹션)
UFUNCTION(BlueprintPure, Category = "Speed Boost")
bool IsEffectActive() const;

UFUNCTION(BlueprintPure, Category = "Speed Boost") 
float GetCurrentSpeedMultiplier() const;

void ReapplyCurrentSpeed(); // 속도 재적용 메서드

2. OnRepIsSliding() 함수 수정

void ADCCharacter::OnRepIsSliding()
{
    if (bIsSliding) {
        GetCharacterMovement()->MaxWalkSpeed = SlideSpeed; // 300
    } else {
        // 스피드 부스트 확인 후 적절한 속도 복원
        if (USpeedBoostEffectComponent* SpeedComp = FindComponentByClass<USpeedBoostEffectComponent>()) {
            if (SpeedComp->IsEffectActive()) {
                SpeedComp->ReapplyCurrentSpeed();
            } else {
                GetCharacterMovement()->MaxWalkSpeed = WalkSpeed; // 400
            }
        } else {
            GetCharacterMovement()->MaxWalkSpeed = WalkSpeed; // 400
        }
    }
}

3. OnMovementModeChanged 오버라이드

// DCCharacter.h (protected 섹션)
virtual void OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode) override;

// DCCharacter.cpp
void ADCCharacter::OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode)
{
    Super::OnMovementModeChanged(PrevMovementMode, PreviousCustomMode);
    
    // 수영→걷기 전환 시 스피드 부스트 재적용
    if (GetCharacterMovement()->MovementMode == MOVE_Walking && PrevMovementMode == MOVE_Swimming) {
        if (USpeedBoostEffectComponent* SpeedComp = FindComponentByClass<USpeedBoostEffectComponent>()) {
            if (SpeedComp->IsEffectActive()) {
                SpeedComp->ReapplyCurrentSpeed();
            }
        }
    }
}

💡 기억해라!

1. 델리게이트 vs 가상함수

  • MovementModeChangedDelegate 는 존재하지 않음
  • OnMovementModeChanged 가상함수 오버라이드가 올바른 방법
  • 부모 클래스와 동일한 접근 제한자(protected) 사용

2. 컴포넌트 상태 확인 패턴

if (USpeedBoostEffectComponent* SpeedComp = FindComponentByClass<USpeedBoostEffectComponent>()) {
    if (SpeedComp->IsEffectActive()) {
        // 활성 상태일 때 처리
    }
}

3. 네트워크 동기화 고려사항

  • MulticastSetCharacterSpeed 를 통한 모든 클라이언트 동기화
  • 서버 권한 확인 (HasAuthority()) 필수

🧠 배운 것

  • 하드코딩된 속도 설정은 다른 시스템과의 상호작용에서 문제를 일으킬 수 있다
  • 상태 확인 후 조건부 복원이 시스템 간 충돌을 방지하는 핵심이다
  • 언리얼의 CharacterMovementComponent는 Mode 변경 시 내부적으로 속도를 초기화한다
  • 이런 문제를 피하려면 상태 관리와 복원 로직을 항상 고려해서 설계해야 한다는 것을 깨달았다.

0개의 댓글