본문 바로가기

게임프로그래밍/실습1

[언리얼 실습] 53. 원할 때만 체력바가 보이게 하기


목차

  1.  최초에 체력바 안보이게 하기
  2.  타격시 체력바 보이게 하기
  3.  일정 거리에서 벗어나면 체력바 안보이게 하기
  4.  에너미 사망시 체력바 안보이게 하기

1. 최초에 체력바 안보이게 하기

 

에너미 생성시 현재 체력바가 같이 보이는데 이부분을 수정하여 전투상태가 들어가야 체력바가 보이게 수정할 것이다. 그렇게 하기 위해서는 가장 처음에는 체력바가 보이지 않게 해야한다.

 

BeginPlay() 함수로 들어가자.

 

void AEnemy::BeginPlay()
{
	Super::BeginPlay();
	if(HealthBarWidget)
    {
	 HealthBarWidget->SetVisibility(false);
    }
}

 

이제 타격을 받으면 체력바가 보이게 해볼 것이다.


2. 타격시 체력바 보이게 하기

 

이제 에너미가 플레이어에게 타격을 받으면 체력바가 보이게 표시할 것이다.

 

현재 에너미의 피격은 GetHit_Implementation() 함수에서 다루고 있다.

 

void AEnemy::GetHit_Implementation(const FVector& ImpactPoint)
{
	if (HealthBarWidget)
	{
		HealthBarWidget->SetVisibility(true);
	}
    
    // 생략
}

 

처음 BeginPlay에서 했던 것과 불리언 설정을 반대로 해주면 된다.


3. 일정 거리에서 벗어나면 체력바 안보이게 하기

 

이제 플레이어가 에너미에게서 어느정도 떨어지면 체력바가 보이지 않게 바꾸어볼 것이다.

 

방식은 다음과 같다. 에너미가 피해를 받으면 피해를 준 액터를 저장해서 해당 액터를 CombatTaget으로 인식하게 하는 것이다.

 

그리고 이 액터와의 거리를 계산해서 체력바를 보일지 안보일지 여부를 정하면 된다. 추후에 에너미의 공격까지 구현하면 해당 Target이 에너미의 공격 대상이 될 것이다.

 

// 에너미.h

UPROPERTY()
AActor* CombatTarget;

 

단순하게 AActor 포인터에 저장하도록 하자.

 

현재 에너미에게 누가 피해를 주는지는 TakeDamage() 함수에서 알 수 있다.

 

해당 함수의 매개변수에는 EventInstigator와 DamageCauser가 있는데 DamageCauser는 발생시킨 액터 그 자체 (현재로서는 무기)이기 때문에 CombatTaget으로 설정할 액터가 아니고 EventInstigator를 통해 해당 컨트롤러가 조종하고 있는 액터를 가져와 이를 CombatTaget으로 지정해야 한다.

 

float AEnemy::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
	if (Attributes && HealthBarWidget)
	{
		Attributes->ReceiveDamage(DamageAmount);
		HealthBarWidget->SetHealthPercent(Attributes->GetHealthPercent());
	}

	CombatTarget = EventInstigator->GetPawn(); // 추가

	return DamageAmount;
}

 

Pawn은 AActor의 하위 클래스이기 때문에 AActor 포인터에 저장이 될 수 있다.

 

이제 CombatTaget과의 거리를 계산해서 체력바을 보일지 말지의 여부를 결정하면 된다.

 

캐릭터와의 거리는 실시간으로 계산하는 영역일 것이다. 그러니 Tick() 함수에서 이를 계산하도록 하자.

 

void AEnemy::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (CombatTarget)
	{
		const double DistanceToTarget =
		(CombatTarget->GetActorLocation() - GetActorLocation()).Length();
	}

}


Length() 함수나 또는 Size() 함수를 통해 백터의 길이(magnitude)를 구할 수 있다.

 

이제 이 크기가 우리가 설정한 길이보다 먼지 아닌지 확인해서 체력바의 표시 여부를 지정하면 된다. 이 '우리가 설정한 길이'의 경우 하드코딩하는 것 보다는 에디터에서 수정할 수도 있게 하는 것이 좋을 것이다.

 

다시 헤더파일로 이 제한거리를 만들도록 하자.

 

UPROPERTY(EditAnywhere)
double CombatRadius = 500.f;

 

이제 이 거리를 DistanceToTarget 과 비교하면 된다.

 

void AEnemy::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (CombatTarget)
	{
		const double DistanceToTarget = (CombatTarget->GetActorLocation() - GetActorLocation()).Length();

		if (DistanceToTarget > CombatRadius)
		{
			CombatTarget = nullptr;
			if (HealthBarWidget)
			{
				HealthBarWidget->SetVisibility(false);
			}
		}
	}

}

 

 

타겟과의 거리가 CombatRadius보다 길어지면 CombatTarget을 없애고 이후 헬스바를 안보이게 한다.

 

 

 

CombatRadius를 Debug Sphere로 보이게 하고 테스트 하였다. CombatRadius를 벗어나면 체력바가 안보이는 것을 볼 수 있다.


 

4. 에너미 사망시 체력바 안보이게 하기

 

마지막으로 에너미가 죽을 때 체력바가 안보이게 하자.

 

void AEnemy::Die()
{
//생략
 if (HealthBarWidget)
 {
  HealthBarWidget->SetVisibility(false);
 }

}

 

간단하게 Die 함수에서 헬스바를 안보이게 하면 된다.

 

이렇게 해서 체력바와 관련된 작업이 끝났다.