조 : Team12 RPG
프로젝트 명 : Katana(가제)
목표 : Kannagi Usagi / Sekiro Like와 비슷한 보스전투 구현
기여 파트
오늘은 Enemy의 Behavior Tree 구조를 세키로/소울라이크 보스전에 가깝게 수정했다.
기존 구조는 SelectNextAction에서 이동, 일반공격, 강공격을 랜덤으로 고르는 방식이었다. 하지만 실제 소울라이크 보스는 플레이어에게 계속 직선으로 접근하기보다는, 일정 시간 플레이어를 바라보며 좌우로 간을 보다가 공격 타이밍에 돌진하거나 특수 공격을 사용한다.
그래서 전투 흐름을 다음처럼 변경했다.
Strafe Around Target
-> Select Next Action
-> 공격 분기
새로운 BTTask_StrafeAroundTarget를 추가했다.
이 Task는 일정 시간 동안 Enemy가 플레이어를 바라본 상태로 좌우 스트레이프 이동을 하게 만든다. 스트레이프 중에는 이동 속도를 낮추고, Task가 끝나면 다시 돌진용 속도로 복구한다.
StrafeMoveSpeed = 150~300
AfterStrafeMoveSpeed = 600
StrafeDuration = 2~5초
이를 통해 Enemy가 공격 전 바로 접근하지 않고, 플레이어 주변을 돌며 간을 보는 움직임을 만들 수 있게 됐다.
BTTask_SelectNextAction의 역할도 변경했다.
기존에는 이동, 일반공격, 강공격을 모두 선택했지만, 이제 이동은 전투 루프에 고정하고 SelectNextAction은 공격 패턴만 선택한다.
현재 공격은 총 4종이다.
SelectedAction = 1, SelectedPattern = 0 -> 일반공격 0
SelectedAction = 1, SelectedPattern = 1 -> 일반공격 1
SelectedAction = 2, SelectedPattern = 0 -> 근접 강공격
SelectedAction = 2, SelectedPattern = 1 -> 원거리 특수 강공격
일정 거리 이상 떨어져 있으면 원거리 특수 강공격을 선택하고, 그 외에는 일반공격 2종과 근접 강공격 1종 중 가중치 랜덤으로 선택한다.
if (DistanceToTarget >= FarSpecialAttackDistance)
{
SelectedAction = 2;
SelectedPattern = 1;
}
else
{
// Normal 0, Normal 1, Strong 0 중 랜덤 선택
}
최종 BT 구조는 다음과 같다.
ROOT
└─ Main Sequence
├─ Service: Update Target Info
│
├─ Strafe Around Target
├─ Select Next Action
│
└─ Selector_Attack
│
├─ FarAttack
│ ├─ Decorator: SelectedAction == 2
│ ├─ Decorator: SelectedPattern == 1
│ ├─ Rotate To Target
│ ├─ Execute Attack
│ └─ Wait
│
└─ ApproachAttack
├─ Set Movement Speed: 600
├─ Move To: TargetActor
├─ Rotate To Target
│
└─ AttackSelector
│
├─ NormalAttack
│ ├─ Decorator: SelectedAction == 1
│ ├─ Execute Attack
│ └─ Wait
│
└─ StrongAttack
├─ Decorator: SelectedAction == 2
├─ Decorator: SelectedPattern == 0
├─ Execute Attack
└─ Wait
이 구조에서 원거리 특수 강공격은 접근하지 않고 바로 실행된다.
반면 일반공격과 근접 강공격은 먼저 Move To TargetActor로 플레이어에게 돌진한 뒤 실행된다.
거리 기반 공격 선택이 제대로 동작하는지 확인하기 위해 EnemyCharacterBase::Tick()에서 Enemy와 Player 사이의 거리를 화면에 출력하도록 했다.
const float DistanceToPlayer = FVector::Dist(GetActorLocation(), PlayerPawn->GetActorLocation());
GEngine->AddOnScreenDebugMessage(
1,
0.f,
FColor::Green,
FString::Printf(TEXT("Enemy Distance To Player: %.2f"), DistanceToPlayer)
);
이를 통해 PIE 중 실시간으로 거리를 확인하면서 FarSpecialAttackDistance 값이 적절한지 조정할 수 있게 됐다.
오늘 작업으로 Enemy AI의 전투 흐름이 단순 랜덤 행동에서 벗어나, 다음과 같은 형태로 바뀌었다.
플레이어 락온
-> 좌우 스트레이프
-> 거리 기반 공격 선택
-> 원거리 특수공격 또는 돌진 공격
-> 다시 스트레이프
아직 실제 공격 Montage와 판정은 연결되지 않았지만, 보스 AI의 기본 전투 리듬은 어느 정도 잡힌 상태다.