언리얼4 C++ 재장전 (Reload System)

Intro

  • C++ 재장전 구현

필요한 변수, 함수 선언

UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
int32 RemainAmmo;

UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
int32 Magazine;
    
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
bool IsReloading;

void Reload();	
void ReloadEnd();

Reload 구현

변수 초기화

Ammo = 0; // 장전된 탄약
Magazine = 30; // 최대 탄약
RemainAmmo = 0; // 가지고있는 탄약

키 바인딩

PlayerInputComponent->BindAction("Reload", IE_Pressed, this, &AFPSPlayer::Reload);

Reload키(R)를 누르면 Reload 함수가 실행된다.

Reload 함수

void AFPSPlayer::Reload()
{
	if (Aiming == false && CheckWeapon == true && IsReloading == false && Ammo != Magazine && RemainAmmo != 0) 
	{
		/*UE_LOG(LogTemp, Log, TEXT("Reload"));*/
		FPSAnim->PlayReload();
		IsReloading = true;
	}
}

Reload 함수는 모든 조건이 만족하면 재장전 몽타주를 실행시키고 IsReloading 상태를 true로 바꾼다.

Reload 몽타주

몽타주 초기화

static ConstructorHelpers::FObjectFinder<UAnimMontage> Reload(TEXT("AnimMontage'/Game/Character/Swat/SwatAnim/Reloading_Montage.Reloading_Montage'"));
if (Reload.Succeeded())
{
    ReloadMontage = Reload.Object;
}

몽타주 재생

void UFPSAnimInstance::PlayReload()
{
	Montage_Play(ReloadMontage, 1.0f);
}

Reload 몽타주는 다음과 같이 본으로 다시 블렌딩하여 상체는 재장전 모션을 취하고 하체는 다른 자세를 취하게한다.

1

애님 노티파이

재장전이 끝나는 지점에 ReloadEnd 노티파이를 추가한다.

2

Notify 함수 사용

UFUNCTION()
void AnimNotify_ReloadEnd();
void UFPSAnimInstance::AnimNotify_ReloadEnd()
{
	FPSPlayer = Cast<AFPSPlayer>(TryGetPawnOwner());
	UE_LOG(LogTemp, Log, TEXT("Reload"));
	FPSPlayer->ReloadEnd();
	
}

ReloadEnd 노티파이가 호출되면 Player클래스에 정의된 ReloadEnd함수를 호출하도록한다.

ReloadEnd 함수

void AFPSPlayer::ReloadEnd()
{
	UE_LOG(LogTemp, Log, TEXT("ReloadComplete"));
	if ((Magazine - Ammo) > RemainAmmo)
	{
		Ammo = (RemainAmmo + Ammo);
		RemainAmmo = 0;
	}
	else
	{
		RemainAmmo = RemainAmmo - (Magazine - Ammo);
		Ammo = (Magazine - Ammo) + Ammo;
	}
	UE_LOG(LogTemp, Log, TEXT("Current Ammo %d / %d"), Ammo, RemainAmmo);
	IsReloading = false;
}

ReloadEnd함수가 호출되면 가지고있는 탄약수에 따라 최대 탄약수 만큼 장전량을 채운다음 IsReloadingfalse로 바꾸어준다.

실행 결과

gif

3

참고문서

댓글남기기