우선, 칸나가 권총을 들고 있을 땐 EX스킬을 사용할 수 있어야 하고, 소총을 들고 있을 땐 EX스킬을 사용할 수 없어야 한다.
KannaCharacter 클래스가 각 무기 종류에 대해 의존성을 가지는 것은 피하려고 한다. 오직 AGun 클래스에만 의존하게 하는 것이 목표이다.
따라서 AGun 클래스에 KannaCharacter에서 사용할 여러 프로퍼티를 만들어주었다.
// AGun.h 중 일부
bool HasExSkill; //EX 스킬을 사용 가능한 총인지
bool ExSkillReady; // true 시 다음 발사 시 EX 스킬이 나간다.
//KannaCharacter에서 호출할 함수
FORCEINLINE virtual void ReadyExSkill() {ExSkillReady = true;}
ReadyExSkill은 가상함수로 만들었다.
EX 스킬을 사용할 수 있는 무기에서는 ReadyExSkill을 오버라이딩하여, 함수가 호출되면 동적 바인딩이 되어 추가 작업을 할 수 있도록 하기 위해서이다.
그렇게 되더라도 KannaCharacter는 현재 무기가 EX 스킬을 쓸 때 무슨 일을 하는지 모른다. 좋게 말하면 알 필요가 없다.
나름대로 최선의 디자인을 만들었다.
앞서 EX 스킬은 투사체를 쏘는 방식으로 하기로 결정한 바가 있다.
따라서 권총을 쏘면 SpawnActor로 소환할 투사체의 클래스인 ExProjectileClass를 Pistol.h에 넣어주었다.
//Pistol.h
UPROPERTY(EditDefaultsOnly)
TSubclassOf<AProjectile> ExProjectileClass;
주로 TPS 게임에서 공격 판정을 담당하는 라인 트레이싱은 화면 중앙에서 앞으로 뻗어나가는 방향을 사용한다.
만약 그렇게 하지 않고 총구의 시작점에서 총구의 방향대로 라인트레이싱을 하면, 총구가 향하는 방향은 플레이어의 조준 방향과 다르기 때문에 조준점에 조준하고 쏴도 맞지 않는 문제가 발생한다.
원래는 이러한 점 때문에 EX 스킬 투사체도 적당히 화면 정중앙보다 조금 앞 쪽에서 시작하여 정면으로 날아가도록 하려고 했는데, 다른 분이 좋은 방법을 생각해내신 포스팅을 찾았다.
void APistol::FireExSkill(FHitResult& HitResult)
{
//투사체 스폰
FVector SpawnLocation = Muzzle->GetComponentLocation();
FRotator SpawnRotation = UKismetMathLibrary::FindLookAtRotation(SpawnLocation, HitResult.ImpactPoint);
FActorSpawnParameters Param;
Param.Instigator = GetInstigator();
GetWorld()->SpawnActor<AProjectile>(ExProjectileClass, SpawnLocation, SpawnRotation, Param);
ExSkillReady = false;
}
인자로 들어온 FHitResult는 라인트레이싱의 결과가 될 것이다.
UKismetMathLibrary::FindLookAtRotation 함수를 사용하여 손쉽게 시작점 -> 도착점 방향의 FRotator를 구할 수 있다.
여기에서는 시작점은 Muzzle, 도착점은 HitResult.ImpactPoint이다.
그렇게 구한 Rotator를 SpawnActor의 인자로 넣어주면, Projectile은 스폰되는 즉시 그 방향으로 날아간다. 따라서 자연스럽게 총구에서 ImpactPoint를 향해 날아간다.
이제 Fire 함수에서 ExSkillReady가 true일 시 저 함수를 호출한다.
void APistol::Fire(FVector& StartPoint, FVector& Direction)
{
Super::Fire(StartPoint, Direction);
FHitResult HitResult;
FVector EndPoint = StartPoint + Direction * Range;
if (GetWorld())
{
if (GetWorld()->LineTraceSingleByChannel(
HitResult,
StartPoint,
EndPoint,
ECollisionChannel::ECC_Visibility))
{
if (HitResult.GetActor())
{
if (ExSkillReady && ExProjectileClass)
{
FireExSkill(HitResult);
}
else
{
/* 생략 */
}
}
}
}
/* 생략 */
);
}
그리고 APistol의 자식 클래스인 BP_Pistol에서 ExProjectileClass를 할당해주었다.
BP_Projectile보다 크기만 좀 크고, 더 느린 버전이다.
그리고 인풋 액션 IA_ExSkill을 만들어 KannaCharacter에서 바인딩 시켜주고(반복적인 내용이므로 여기서는 생략), 콜백 함수 ExSkill을 만들었다.
void AKannaCharacter::ExSkill()
{
if (CurrentWeapon->HasExSkill && CanUseExSkill()) //Ex 스킬을 쓸 수 있는 무기라면
{
CurrentWeapon->ReadyExSkill(); // 무기에 델리게이트
Attributes->SubtractExGaugePercent(0.3f);
}
}
CanUseExSkill은 단순히 현재 EX 게이지가 0.3 이상인지 검사하는 한줄짜리 함수이다.
KannaCharacter는 현재 무기가 뭔진 모르지만 아무튼 EX스킬을 사용할 수 있다면, 무기에 EX 스킬을 준비시키고 게이지를 감소시킨다.
테스트 결과, 3코스트 이상 충전되었을 때 T를 누르고 총을 발사하면 게이지가 잘 깎이고, 투사체도 잘 나가는 것을 확인할 수 있었다.
이제 투사체가 실제로 데미지를 주도록 할 생각이다.
+ Enemy의 TakeDamage 함수에 헤드샷일시 추가 데미지 / 플레이어 감지 로직 적용
float AEnemy::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
if (Attributes)
{
if (DamageEvent.IsOfType(FPointDamageEvent::ClassID))
{
FPointDamageEvent PointDmg = *((FPointDamageEvent*)(&DamageEvent));
{
UE_LOG(LogTemp, Warning, TEXT("Hit Point: %s"), *(PointDmg.HitInfo.BoneName.ToString()));
if (PointDmg.HitInfo.BoneName == FName("Neck")) //헤드샷 맞으면 추가 데미지
{
DamageAmount += 25.f;
}
}
}
Attributes->ReceiveDamage(DamageAmount);
if (Attributes->IsDead())
Die(DamageEvent);
}
UE_LOG(LogTemp, Warning, TEXT("Enemy HP: %f"), Attributes->GetCurrentHealth())
// 플레이어 감지 자극
UAIPerceptionSystem* PerceptionSystem = UAIPerceptionSystem::GetCurrent(this);
PerceptionSystem->OnEvent(FAITouchEvent(this, EventInstigator->GetPawn(), GetActorLocation()));
return DamageAmount;
}
'언리얼 엔진 5 > 개발 일지' 카테고리의 다른 글
[UE5] 블루아카이브 TPS게임 개발일지 (55) - EX 스킬 제작 3 (UParticleSystem) (0) | 2024.02.02 |
---|---|
[UE5] 블루아카이브 TPS게임 개발일지 (54) - EX 스킬 제작 2 + LSP (0) | 2024.02.02 |
[UE5] 블루아카이브 TPS게임 개발일지 (52) - 리팩토링 (0) | 2024.01.30 |
[UE5] 블루아카이브 TPS게임 개발일지 (51) - EX 게이지 제작 (0) | 2024.01.28 |
[UE5] 블루아카이브 TPS게임 개발일지 (50) - 맵 제작 (2) | 2024.01.28 |