-
블루아카이브 루트슈터 팬게임 프로젝트(19) - 체력 회복 시스템루트슈터 프로젝트 2024. 1. 21. 01:13
안녕하세요. 이번에는 플레이어의 체력 회복 시스템에 대해 구현해보았습니다. 콜오브듀티와 같은 게임들을 보면 플레이어가 체력을 입은 후 일정시간 데미지를 입지 않으면 체력이 서서히 회복됩니다. 제 게임 또한 자동회복 시스템을 구현해 보기로 하였습니다.
제 게임에서는 플레이어가 3초간 피해를 입지 않았다면 초당 최대 체력의 10%를 회복하도록 해보겠습니다.
PlayerCharacter.h
public: bool bCanRegen = true; UFUNCTION() void PlayerHPRegen();
플레이어 클래스에 현재 체력을 리젠할 수 있는지 표시해주는 bool 변수, 그리고 플레이어 체력을 리젠할 수 있게 해주는 함수를 하나 선언해줍니다. 이 함수에 UFUCTION()을 붙여준 이유는 밑에서 서술하겠습니다.
PlayerCharacter.cpp
void APlayerCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); if(bCanRegen) playerNowHP = FMath::Clamp(playerNowHP + (playerMaxHP * 0.1 * DeltaTime), 0.0f, playerMaxHP); }
지속적으로 체력을 회복할 수 있게 해주는데에는 Tick 함수에서 하는것이 가장 좋을것이라고 생각했습니다. 여기서 플레이어가 체력을 회복할 수 있는 상태인지를 방금 선언한 bool 변수에서 체크하고, 체력을 회복할 수 있는 상태라면 1초당 최대 체력의 10%만큼 하게 해줍니다.
float APlayerCharacter::TakeDamage(float DamageAmount, FDamageEvent const &DamageEvent, AController *EventInstigator, AActor *DamageCauser) { Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); bCanRegen = false; if(playerNowHP / playerMaxHP <= 0.3f) playerNowHP -= (DamageAmount*0.6); else playerNowHP -= DamageAmount; //플레이어 체력 자동 회복 FLatentActionInfo regen; regen.Linkage = 0; regen.CallbackTarget = this; regen.ExecutionFunction = "PlayerHPRegen"; regen.UUID = GetUniqueID(); UKismetSystemLibrary::RetriggerableDelay(GetWorld(), 3.0, regen); return playerNowHP; } void APlayerCharacter::PlayerHPRegen() { bCanRegen = true; }
그리고 플레이어가 데미지를 입었을 때 호출되는 함수입니다. 데미지를 입었다면 체력을 리젠할 수 없는 상태이므로 bCanRegen을 false로 바꿔줍니다. 이렇게 된다면 위의 Tick 함수에서 체력 리젠이 멈출 것입니다.
그리고 여기서 RetriggerableDelay라는 함수가 나오는데, 프로그래머가 정의한 시간의 딜레이 후에 특정 함수가 실행되게 해주는 기능을 제공합니다. 아마 딜레이에 대해 가장 잘 알려진 기능이 Timer 기능인데, Timer 기능은 특정 시간을 간격으로 실행되게 해주는 것에 특화되있기도 하고, 이미 Timer로 기능을 구현해보았을때 체력회복이 제대로 되지 않는 문제점이 발생하였습니다. 그래서 찾아본 결과 이 기능을 발견해서 사용해본 결과, 아직까지는 체력회복이 되지 않는 오류는 발생하지 않았습니다.
FLatentActionInfo 구조체는 딜레이 후 어떤 Action을 취해야 되는지 정보를 저장해두는 구조체입니다. ExecutionFuction에 실행할 함수를 적으면 되는데, 여기서 지정하는 함수는 꼭 UFUCTION() 으로 지정해두어야 호출할 수 있습니다.
RetriggerableDelay 함수의 인수는 월드 오브젝트, 얼마나 긴 딜레이를 줄 것인지, 그리고 위에서 지정해놓은 FLatentActionInfo 구조체를 적어두면 됩니다. PlayerHPRegen 함수는 플레이어가 체력을 회복할 수 있는 상태라고 알려주는 bool 변수를 다시 true로 바꿔주면 됩니다.
https://gist.github.com/MichaelGatesDev/326da2b3e5fd76bf9977ad480d12caa3
이곳에서 RetriggerableDelay의 사용법을 확인할 수 있습니다.
결과물입니다. 피해를 입고 3초가 지나면 플레이어가 다시 체력을 회복하는 것을 볼 수 있습니다.
'루트슈터 프로젝트' 카테고리의 다른 글
블루아카이브 루트슈터 팬게임 프로젝트(21) - 게임 저장 시스템 (1) 2024.01.23 블루아카이브 루트슈터 팬게임 프로젝트(20) - 인벤토리 아이템 판매 시스템 (1) 2024.01.21 블루아카이브 루트슈터 팬게임 프로젝트(18) - 적 스폰 시스템 & 웨이브 게임모드(3) (0) 2024.01.20 블루아카이브 루트슈터 팬게임 프로젝트(18) - 적 스폰 시스템 & 웨이브 게임모드(2) (0) 2024.01.19 블루아카이브 루트슈터 팬게임 프로젝트(17) - 체력 컴포넌트 교체 (0) 2024.01.17