※ 해당 기록은 Unreal 5.5.3 버전을 기준으로 작성되었습니다.
보스의 두 번째 패턴인 탄막 패턴을 구현했다.
투사체를 날리기 위해서 UProjectileMovementComponent를 사용했다. 이 컴포넌트 안에 있는 변수와 함수를 이용해 탄막 패턴을 만들었다. 우선은 투사체가 중력의 영향을 받지 않기 위해 다음과 같이 작성했다. Movement->ProjectileGravityScale = 0.0f; 이러면 중력에 영향을 받지 않는다. 또 원하는 시간만큼 날아가서 자동으로 파괴되도록 하기 위해 SetLifeSpan(LifeTime)도 사용했다. LifeTime은 따로 UPROPERTY(EditAnywhere)로 열어두어 에디터에서도 수정하기 편하게 했다. 충돌 처리는 추후에 할 예정이다.
현재 공격을 담당하는 함수는 FSM에서 호출하고 있다. 마찬가지로 CurtainFire()에서는 우선 FTimer를 설정하게 했다. 함수는 다음과 같다.
GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &ABoss::SpawnProjectile, 0.4f, true, 4.f);
여기서 볼 것은, 네 번째 인자의 함수를 float 초 간격으로 호출하고, 마지막 의 float초 동안 delay 후 첫 호출하겠다는 뜻이다. 내가 의도한 것은 4초 후, 4초간 총 10번 함수를 호출하도록 한 것이다.
실제 스폰을 담당하는 SpawnProjectile()이다. 우선 함수가 호출될 때마다 fireCounter++을 통해 10회 불렸는지 체크하고, 참이면 타이머를 끈다. 반복문으로 플레이어 방향을 기준으로 좌우 15도, 30도 방향으로 다섯 갈래로 탄막을 발사한다.
void ABoss::SpawnProjectile()
{
if (fireCounter >= 10)
{
//10번 쏘면 타이머 끄기
GetWorldTimerManager().ClearTimer(TimerHandle);
fireCounter = 0;
return;
}
FActorSpawnParameters spawnParams;
spawnParams.bNoFail = true;
spawnParams.Owner = this;
//기준 각은 플레이어를 바라보게 하고싶다.
APlayerController* controller = GetWorld()->GetFirstPlayerController();
FVector playerLocation = controller->GetPawn()->GetActorLocation();
FRotator BaseRotation = UKismetMathLibrary::FindLookAtRotation(this->GetActorLocation (), playerLocation);
// 중앙 기준 각도
float BaseAngle = BaseRotation.Yaw;
// 좌우로 퍼지는 각도 차이
float AngleOffset = 15.0f;
for (int32 i = -2; i < 3; i++)
{
float angle = BaseAngle + (i * AngleOffset);
FRotator fireAngle = FRotator(0.f, angle, 0.f);
ACurtainFireProjectile* projectile = GetWorld()->SpawnActor <ACurtainFireProjectile>(ProjectileFactory,
ArrowComp->GetComponentTransform(), spawnParams);
projectile->SetVelocity(fireAngle.Vector ());
}
fireCounter++;
}
의도치 않은 결과이지만 어째선가 처음의 기 모으는 듯한 프래임이 지나고 발사 모션 근처에서 공격이 시작한다. 운이 좋게 시간대가 맞은 것 같다.
장판 패턴을 구현하고, 공격에 대한 충돌 처리가 필요하다. 데미지를 주고받는 부분이 구현되지 않았다. 앞의 것들이 끝나면, Monster도 구현할 계획이다.