[Unreal_C++_DarkSoul]#16_런 타임 AI 실행 여부
런 타임 중 AI의 BT(Behavior Tree) 실행 여부를 관리합니다.
Overview
- 개요
- 코드
- 정리
#0. 개요
1. 문제
- 적 객체는 저마다 Behavior Tree를 실행하는 AI 객체를 Controller로 갖습니다.
- 하지만, AI 객체는 BT를 지속적으로 실행할 뿐 적 객체가 어떠한 상태인지 고려하지 않습니다. 물론, GetPawn() 함수를 통해 Agent(AI의 통제를 받는 객체)를 가져와 Agent의 상태를 확인하는 방법이 존재하지만, BT의 각 BTTaskNode 실행 함수에서 GetPawn() 함수를 매번 호출해야 하는 비효율적인 코드 중복이 발생합니다.
- 따라서, 런 타임 중 BT의 실행 여부를 별도로 관리하는 방법이 필요합니다.
2. 해결 방안
- AIController 유형의 객체가 갖는 UBrainComponent 유형의 컴포넌트를 활용합니다.
- UBrainComponent는 Unreal Engine에서 인공지능 시스템을 구현하기 위해 활용되는 컴포넌트입니다. UBrainComponent는 AAIController 객체에 부착되어 사용됩니다. UBrainComponent는 AI의 동작 및 행동 관리, 상태 관리, 의사 결정 메커니즘, 그리고 통신 및 상호 작용 등의 기능을 포함하며 AI 시스템을 구성하는 중요한 요소입니다.
- 이를 활용해 적 객체가 움직일 수 없는 상태(Stumbling, Death, etc)가 되었을 때, AAController 객체의 BT 수행을 일시 정지하고, 움직일 수 있는 상태(Idle)가 되었을 때, BT 수행을 재개할 수 있도록 수정합니다.
#1. 코드
1. AGameObject::IsStartDamaged()
void AGameObject::IsStartDamaged(AActor* InDamageCauser, float InImpulseAmount)
{
ACharacter* DamageCauserCharacter = Cast<ACharacter>(InDamageCauser->GetOwner());
CheckTrue(!DamageCauserCharacter || !StateComponent || !WeaponComponent);
// #0. Knock Back
KnockBack(DamageCauserCharacter, InImpulseAmount);
// #1. State
OnChangeStateType.ExecuteIfBound(EStateType::E_Stumbling);
// #2. Montage
OnPlayHitAnim.ExecuteIfBound(
StateComponent->GetStateType(),
WeaponComponent->GetWeaponType(),
WeaponComponent->GetCurrentWeapon()->GetComboType(),
-1,
-1
);
// #3. AI
if(!!AIController)
AIController->GetBrainComponent()->PauseLogic("Agent Is Stumbling");
// #4. Collision
GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
}
Details
- AGameObject 클래스의 IsStartDamaged 함수는 AGmaeObject 유형의 객체가 피격 당할 시 호출되는 함수입니다. 함수가 구현한 내용에 대해 간단하게 설명하자면, 해당 객체의 상태 값을 변경하고, 피격 애니메이션을 재생하며, 넉백 됩니다.
- AGameObject 클래스의 IsStartDamaged 함수는 추가적으로 AAIController 유형의 객체가 갖고 있는 UBrainComponent를 통해 AI 동작을 일시적으로 정지시킵니다. 이를 통해, Stumbling 상태의 객체가 AI의 "Behavior Tree"가 정의하는 동작을 지속적으로 수행하는 오류를 방지합니다.
2. AGameObject::IsEndDamaged()
void AGameObject::IsEndDamaged()
{
// #0. State
OnChangeStateType.ExecuteIfBound(EStateType::E_Idle);
// #1. AI
if(!!AIController)
AIController->GetBrainComponent()->ResumeLogic("Agent Is Idle");
// #2. Rotation
bUseControllerRotationYaw = true;
GetCharacterMovement()->bOrientRotationToMovement = false;
// #3. Character Movement
GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
GetCharacterMovement()->SetMovementMode(EMovementMode::MOVE_Walking);
}
Details
- AGmameObject 클래스에서 정의하는 IsEndDamaged() 함수는 AGameObject 유형의 객체가 "피격 상태(Stumbling)"에서 벗어나 기존의 Idle 상태로 돌아가기 위한 동작들을 정의합니다.
- 1번 주석을 살펴보면, AAIController 객체의 Brain Component를 가져와 AI 동작을 재개시킵니다.
#2. 정리
- AAIController가 갖는 UBrainComponent 유형의 컴포넌트는 인공 지능 동작과 의사 결정을 관리하는 컴포넌트입니다.
- 게임 객체가 움직일 수 없는 상태(피격당했을 때, 혹은 쓰러졌을 때)가 되었을 때, AAIController에게 이를 알릴 수 있는 방법으로 AAIController의 UBrainComponent를 활용할 수 있습니다.
'개인프로젝트' 카테고리의 다른 글
[Unreal_C++_DarkSoul]#18_기능 구현, Sound (0) | 2023.07.23 |
---|---|
[Unreal_C++_DarkSoul]#17_기능 구현, Grid 클래스 (0) | 2023.06.03 |
[Unreal_C++_DarkSoul]#15_문제 해결, Data Table 로드 함수 (1) | 2023.05.08 |
[Unreal_C++_DarkSoul]#14_문제 해결, Actor Component 간 소통 (0) | 2023.03.26 |
[Unreal_C++_DarkSoul]#13_기능 구현, Impact Effect (0) | 2023.02.05 |