문제 상황
- 캐릭터가 스태미너라는 자원을 활용해 달리기, 구르기와 같은 행동을 하고 코스트를 소모
- 그 과정에서 구르기를 하는 도중에 다시 Shift(구르기 버튼)이 입력되면 스태미너만 소모되고 행동은 수행되지 않음
- 심지어 Shift를 여러번 누르면 여러번 누르는 만큼 스태미너가 소모됨
예) 구르기 1번을 수행하는 도중 Shift 4번 입력 (스태미너가 구르기 4번치만큼 모두 소모)
해결 과정
void APlayerCharacter::Input_OnRoll()
{
static constexpr auto PlayRate{1.3f};
if (!CR4S_ENSURE(LogHong1,Status->ConsumeResourceForRoll()) return;
StartRolling(PlayRate);
}
///////////////////////////////////////////////////////////////////////
bool UBaseStatusComponent::ConsumeResourceForRoll()
{
if(GetCurrentResource()>=BaseStatus.RollStaminaCost;)
{
AddCurrentResource(-BaseStatus.RollStaminaCost);
OnResourceConsumed();
return true;
}
return false;
}
- ConsumeRsourceForRoll을 구르기 입력이 가능한 상태인지 확인하기 위해 사용
- 생각해 보니 조건문 안에서 구르기가 확인 가능한 상태인지를 판별하면서 동시에 그만큼의 스태미너 소모를 함께 수행
- 조건 확인용 그리고 실제 소모용 함수를 나누어 구현할 필요성 인지
bool UBaseStatusComponent::HasEnoughResourceForRoll() const
{
return GetCurrentResource()>=BaseStatus.RollStaminaCost;
}
void UBaseStatusComponent::ConsumeResourceForRoll()
{
AddCurrentResource(-BaseStatus.RollStaminaCost);
OnResourceConsumed();
}
void APlayerCharacter::Input_OnRoll()
{
static constexpr auto PlayRate{1.3f};
if (!CR4S_ENSURE(LogHong1,Status->HasEnoughResourceForRoll()
&& LocomotionAction!=AlsLocomotionActionTags::Rolling)) return;
StartRolling(PlayRate);
Status->ConsumeResourceForRoll();
}
- HasEoughResourceForRoll : 현재 Resource가 Roll을 할만큼의 여유분이 존재하는지 확인하는 함수
- ConsumeResourceForRoll : 실질적으로 Resource를 RollStaminaCost 만큼 감소시키는 함수
- Input_OnRoll 수정
- 현재 스태미너가 충분한지 확인하기 위해 HasEnoughResourceForRoll 사용
- 현재 Roll을 이미 하고 있는지 판별하기 위한 조건 추가
- Roll 관련 몽타주를 재생시킨 후에 실질적인 스태미너 감소 함수 호출
결론 및 고찰
- 조건문에서 현재 리소스가 충분한지 확인하는 용도로 사용할 함수에 리소스 감소 로직까지 함께 사용하면서 생긴 문제
- 더불어 조건문에서 bool값을 반환받기 위해 사용한 함수이므로 '호출'이 되는 시점에서 해당 함수 내의 코드는 모두 수행되는 것을 간과
- 어떤 행동의 가능 유무를 판별하기 위한 함수라면 조건 판별만을 담당하는 것이 바람직
- 실질적인 리소스의 감소와 조건 판별을 2개의 함수로 나누어 구현고 활용함으로써 해결
참고자료