본문 바로가기

게임프로그래밍/실습1

[언리얼 실습] 69. 플레이어 히트 구현하기


목차

  1. GetHit 함수 오버라이드 하기
  2. 히트 애니메이션 재생 중 공격 방지 및 공격 중 맞으면 굳는 현상 수정
  3. 죽은 적의 검에 맞는 현상 수정 및 순찰타이머 정지시키기

1. GetHit 함수 오버라이드 하기

 

함수를 오버라이드 해서 사용할 것이다. 포스팅은 안했지만 강의를 진행하면서 베이스 캐릭터라는 상위 클래스를 만들었는데 이곳에서 구현한 함수를 상속받아 사용할 것이다.

 

UCLASS()
class PRACTICE_API ABaseCharacter : public ACharacter, public IHitInterface
{
protected:

virtual void GetHit_Implementation(const FVector& ImpactPoint) override;

//생략
}
void ABaseCharacter::GetHit_Implementation(const FVector& ImpactPoint)
{
	if (IsAlive()) DirectionalHitReact(ImpactPoint);
	else Die();

	PlayHitSound(ImpactPoint);
	SpawnHitParticles(ImpactPoint);
}

 

다음과 같이 정의하고 자식 클래스에서는 Super:: 키워드로 호출해주면 된다.

 

// 자식 클래스

void AKnight::GetHit_Implementation(const FVector& ImpactPoint)
{
	Super::GetHit_Implementation(ImpactPoint);
}

2. 히트 애니메이션 재생 중 공격 방지 및 공격 중 맞으면 굳는 현상 수정

 

현재 히트 애니메이션이 재생 중이어도 언제든지 다시 공격이 가능하다. 또 공격중에 맞으면 다시는 공격을 하지 못하게 된다. 공격상태가 끝나지 않기 때문이다.

 

캐릭터의 상태를 추가하여 이를 방지하도록 하자.

UENUM(BlueprintType)
enum class EActionState : uint8
{
	EAS_Unoccupied UMETA(DisplayName = "Unoccoupied"),
	EAS_HitReaction UMETA(DisplayName = "HitReaction"), // 추가
	EAS_Attacking UMETA(DisplayName = "Attacking"),
	EAS_EquippingWeapon UMETA(DisplayName = "EquippingWeapon")
};

 

Hit 상태를 하나 추가해준다.

 

void AKnight::GetHit_Implementation(const FVector& ImpactPoint)
{
	Super::GetHit_Implementation(ImpactPoint);

	ActionState = EActionState::EAS_HitReaction;
}

 

이제 히트 했을때 상태를 변경해주자.

 

설정이 끝났으면 이제 원래 상태로 되돌리는 작업을 해야할 차례다. 노티파이를 사용해 이를 실행할 것이며 블루프린트에서 호출 가능한 함수를 만들어야할 것이다.

 

UFUNCTION(BlueprintCallable)
void HitReact();
void AKnight::HitReactEnd()
{
	ActionState = EActionState::EAS_Unoccupied;
}

 

이제 컴파일하고 몽타주에 노티파이를 추가한뒤 애니메이션 블루프린트에서 함수를 호출하면 된다.


3. 죽은 적의 검에 맞는 현상 수정및 순찰타이머 정지시키기 

 

적이 공격 중에 죽으면 콜리전이 사라지질 않아 검에 맞는 현상이 발생한다. 그 문제를 해결하자.

 

void AEnemy::Die()
{
	// 생략
	SetWeaponCollisionEnabled(ECollisionEnabled::NoCollision);
}

 

에너미가 죽는 함수에서 콜리전을 비활성화 시키면 된다.

 

이제 순찰 대기 중에 에너미를 공격하면 순찰타이머가 초기화 되지 않아 그 다음 에너미가 공격할때 에너미가 이동을 해버린다.

 

void AEnemy::GetHit_Implementation(const FVector& ImpactPoint)
{
	Super::GetHit_Implementation(ImpactPoint);
	if (!IsDead()) ShowHealthBar();
	ClearPatrolTimer();
}

 

순찰 타이머를 제거하여 이를 개선한다.

 

이렇게 해서 각종 버그들을 수정하였다.