우리는 앞서 재장전 시스템을 만들었다. 그럼 이제 연사가 가능한 총을 만들어 보자.


우선 마우스 왼쪽 버튼이 release 됐을 때 행동을 구현해야 한다. 완전 간단하다. Character.h를 열어 총을 쏘고있는지 체크할 bool 타입의 변수 하나와 StopFire() 함수를 정의하고 Character.cpp에서 구현과 입력 설정을 마치자.

bool isFiring;
...중략...
void StopFire();
...후략...
void AFPSCppCharacter::StopFire() {
	isFiring = false;
}
InputComponent->BindAction("Fire", IE_Released, this, &AFPSCppCharacter::StopFire);


이제 마우스 왼쪽 버튼을 누르고 있다면 탄환 발사 코드가 계속 반복되어야 한다. 하지만 그저 반복 코드만 넣는다면 결국 무한 루프에 빠져 프로그램은 멈출 것이다.  그렇다면 우리가 필요한 것은 딜레이다. 이제부터 그걸 만들어 보자.


일단 Character.h에 타이머를 정의해주자.

FTimerHandle _timer;


그 다음 Character.cpp를 열어서 OnFire() 함수 구현부를 if문으로 감싸서 isFiring을 체크하도록 만들고 하단 부에 타이머를 넣는다.

if (isFiring) {
	중략...

	GetWorld()->GetTimerManager().SetTimer(_timer, this, &AFPSCppCharacter::OnFire, .075f, false);
}


이렇게 쓴다면 발사 버튼을 누를 때 모든 코드를 최소한 한 번은 실행하고 그 다음 isFiring이 true라면 0.075초 대기한 다음, AFPSCppCharacter의 OnFire 함수를 부를 것이다. 그렇다. 즉 이 코드는 OnFire를 재귀함수로 만들어준다.


결국 버튼이 release 될 때까지 발사 코드를 실행하고 0.075초를 기다린 후 다시 발사하는 코드인 것이다.


하지만 무언가가 빠졌다. 우리는 isFiring을 초기화한 적이 없다. 그럼 이제 알아보기 쉽게 왼쪽 버튼을 눌렀을 때 isFiring을 초기화 해보자.


다음 코드를 찾는다.

InputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCppCharacter::OnFire);


다음과 같이 바꾼다.

InputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCppCharacter::StartFire);


이제 StartFire()를 Character.h에서 정의하고, Character.cpp에서 다음과 같이 구현한다.


void AFPSCppCharacter::StartFire() {
	isFiring = true;
	OnFire();
}


그럼 이제 마우스 왼쪽 버튼을 누르면 isFiring을 true 값으로 바꾸고 OnFire() 함수로 진입할 것이다. 그렇다면 이제 버튼을 누르면 총을 쏘고, 버튼을 놓으면 발사가 멈출 것이다.