diesuki4 2023. 2. 21. 17:29
Unreal Engine: Ultimate Survival Horror Course

 

맵을 좀 더 넓히고 Nav Mesh Bound Volume을 추가한다.


P 키를 누르면 AI의 이동 가능 영역을 확인할 수 있다.

 


AI_Classic Character를 생성한다.


Skeletal Mesh, 애니메이션, 위치를 설정한다.

 


BT_Classic Behavior Tree를 생성한다.

  • 상황에 따른 AI의 행동을 결정한다.

 


BB_Classic Blackboard를 생성한다.

  • Behavior Tree에서 참고할 수 있는 변수 모음으로 볼 수 있다.

 


BT_Classic을 열어서 Blackboard를 BB_Classic으로 설정한다.

  • 우측 상단에서 트리와 블랙보드를 전환할 수 있다.

 


블랙보드에서 Vector3 타입의 targetLocation을 생성한다.

 


BT_Classic에서 Selector 노드를 추가한다.

  • 조건에 따라 가지를 만든다.


Sequence 노드를 추가한다.

  • 등록된 노드들이 좌측부터 순서대로 반복 실행된다.

 

 

BP_RoomTarget 액터를 생성한다.


BillBoard 컴포넌트를 추가한다.

  • 에디터 모드에서 보이며 항상 카메라를 바라본다.

 


타겟 주변의 랜덤 위치를 AI의 목적지로 잡기 위해 Sphere Collision을 추가한다.

  • 여기서는 크기 확인용이고 실질적인 작용은 없다.
  • 실제로는 Radius 변수만 있어도 된다.

 

다른 액터를 Block하지 않도록 Collision Presets: OverlapAllDynamic을 확인한다.


Construction Script에서 Radius 변수와 Set Sphere Radius 노드를 이용해 크기를 설정한다.

 

 

월드에 BP_RoomTarget 여러 개를 배치하고 Radius를 설정한다.

  • 이동 불가 영역이 포함되어도 네비게이션이 그 위치를 지정하지 않기 때문에 문제 없다.

 

 

BT_Classic에서 새로운 BTT_FindRandomRoom Task를 생성하고 Tasks 폴더로 이동한다.

  • Behavior Tree에 배치할 행동 단위이다.

 

 

BTT_FindRandomRoom에서 월드에 배치된 BP_TargetRoom 중 하나를 기준으로 랜덤 위치를 지정하는 부분을 구현한다.

 

Behavior Tree에서 Task가 호출되면 Event Receive Execute AI 이벤트가 실행된다.

 

Random Integer in Range 노드를 이용해 Min ~ Max(Inclusive) 사이의 랜덤 정수를 받아올 수 있다.

 

Get Random Location In Navigable Radius 노드를 이용해 Origin이 중심이고 반지름이 Radius인 구 내에서 AI가 이동 가능한 랜덤 위치 1개를 가져올 수 있다.

  • 실패 시에는 다시 실행해 성공할 때까지 반복한다.

 

Set Blackboard Value as Vector 노드에 Blackboard Key Selector 구조체와 값을 전달하면 Blackboard에 있는 변수의 값을 수정할 수 있다.

  • Key를 변수로 승격하고 Instance Editable에 체크해 값을 할당할 수 있도록 한다.


Finish Execute 노드를 마지막에 배치해 Task 실행이 성공했는지 실패했는지 알릴 수 있다.

  • Success: 체크

 

 

BT_Classic에서 BTT_FindRandomRoom Task를 추가한다.

  • 블루프린트와 같이 우클릭하고 검색해 추가할 수 있다.


변수로 승격시켰던 Target Location Key에 블랙보드의 targetLocation을 지정한다.

 


Move To 노드를 추가하고 목적지 Blackboard Key에 targetLocation을 전달한다.

  • Blackboard Key에 전달된 목적지로 캐릭터가 이동한다.

 


Wait 노드를 추가하고 3초로 설정한다.

  • Wait Time 동안 다음 실행을 지연한다.

 

 

노드 우측 위의 숫자는 실행 순서를 뜻한다.

 


AIC_Classic AIController를 생성한다.


BeginPlay에서 Run Behavior Tree 노드로 BT_Classic Behavior Tree를 실행한다.

 


AI_Classic의 self - Pawn - AI Controller Class에 AIC_Classic 컨트롤러를 설정한다.

 


AI_Classic 캐릭터 여러 개를 월드에 배치하고 테스트한다.

  • Simulate에 체크하고 플레이하면 빙의하지 않고 월드를 관전할 수 있다.
    Unlit 등의 설정도 유지된다.

 

캐릭터가 달리듯이 너무 빨리 움직이는 문제가 있다.


BT_Classic에서 새로운 BTT_SetSpeed Task를 생성한다.

 

 

Event Receive Execute AI 이벤트에 구현한다.

  • Owner Controller: 이 Pawn의 AIController이다.
  • Controlled Pawn: 이 Task를 수행 중인 Pawn이다.


Finish Execute 노드를 배치하고 Success를 설정해 실행 성공 여부를 반환한다.

 


BT_Classic에 BTT_SetSpeed 노드를 추가하고 Max Walk Speed 변수의 값을 설정한다.

 

 

플레이하고 테스트해본다.

 

 

속도는 조절되었으나 애니메이션 속도는 그대로인 문제가 있다.

 

우선 AI의 애니메이션 구조를 파악해보자.

 

AI_Classic의 애니메이션은 ThirdPerson_AnimBP 애니메이션 블루프린트로 설정되어 있다.

 

 

ThirdPerson_AnimBP는 Pawn의 속력을 Speed 변수에 저장한다.

 

 

AnimGrap는 Default라는 상태 머신을 갖는다.

 

 

기본적으로 Idle/Run 상태를 실행하고 점프도 지원한다.

 

 

Idle/Run에서는 Speed 변수의 값에 따라 ThirdPerson_IdleRun_2D 블랜드 스페이스가 재생됨을 알 수 있다.

 

Speed 변수의 값을 조정하면 애니메이션 재생 속도를 조절할 수 있다.

 

 

ThirdPerson_IdleRun_2D 블렌드 스페이스 1D를 열어 수정한다.

  • 현재 ThirdFirsonIdle, ThirdFirsonWalk, ThirdFirsonRun 3개 애니메이션이 점으로 할당되어 있다.
  • 우측 하단의 Asset Browser에서 드래그해서 애니메이션을 점으로 추가할 수 있다.
  • 초록색 점을 조절해서 애니메이션 프리뷰를 볼 수 있다.

 


Axis Settings - Horizontal Axis에서 값을 수정한다. (Blend Space는 Vertical Axis도 갖는다.)

  • Maximum Axis Value: 500
    Speed 값의 최댓값이다.
  • Number of Grid Division: 20
    점을 배치할 수 있는 단위가 20등분된다.

 

ThirdFirsonWalk 점을 225에 맞춘다.

ThirdFirsonWalk 점을 450에 맞춘다.

 


테스트해본다.

 

 

회전이 부드럽지 않고 바로 바뀌어 버리는 문제가 있다.

AI_Classic에서 문제를 수정한다.

 

self - Pawn - Use Controller Rotation Yaw: 해제

  • 컨트롤러의 Z축 회전값을 사용하지 않는다.

Character Movement - Character Movement (Rotation Settings) - Orient Rotation to Movement: 체크

  • 캐릭터가 움직이는 방향으로 회전값을 적용한다.

 


회전 문제도 수정하여 AI의 패트롤 기능 구현에 성공했다.