[UE] AI Basic

허건호·2023년 2월 6일
0

Unreal Engine

목록 보기
3/6
post-thumbnail

Intro

  • 본 학습 자료는 경희대학교 게임 & 실감형 컨텐츠 제작 동아리 Ludens 의 Unreal-Study 자료입니다.

Paragon 에셋 임포트 하기

  • 1주차에서 했던 것과 마찬가지로, 에픽 게임즈 런처 - 상단의 '마켓플레이스' - 'Paragon' 검색 - 'Paragon:Countess' 다운로드 및 프로젝트에 추가해줍시다.

폴더 만들기

  • User 내부에 Enemy 폴더를 만들어줍시다.
    • 우리는 Enemy 에 관련된 것은 모두 이 폴더에 넣을 것입니다.

EnemyBP

  • Enemy 폴더 내에 블루프린트 클래스를 추가해줍니다.

  • 캐릭터 클래스를 골라주시면 됩니다.

  • 이름은 EnemyBP 로 하고, 열어봅시다.

스켈레탈 메시 적용

  • '메시' 컴포넌트 - 스켈레탈 메시 에서 'SM_Countess' 를 선택해줍시다.

  • 둥 떠있는 캐릭터가 나왔습니다. '메시' 컴포넌트의 트랜스폼 - 위치 에서 z 값을 -88.0 으로 바꿔줍시다.

  • 카메라의 방향과 캐릭터가 바라보는 방향이 일치하지 않습니다. '메시' 컴포넌트의 트랜스폼 - 회전 - z 값을 270 으로 바꿔줍시다.

  • 기본 세팅 완료!

EnemyAnimBP

  • 다시 Enemy 폴더로 돌아와서 애니메이션 블루프린트 클래스를 추가해줍시다.

  • Enemy 캐릭터인 S_Countess_Skeleton 를 선택해줍시다.

  • EnemyAnimBP 의 Logic 은 PlayerAnimBP 만큼 복잡하지 않습니다! 바로 시작해봅시다~

변수 생성

  • 먼저, 변수를 생성해줍시다. 하나만 생성하면 됩니다.
    • Speed(플로트) : 캐릭터의 속도를 담을 변수

변수에 값 저장

  • 이벤트 그래프로 가봅시다.

  • 이제 'AnimGraph' 로 가봅시다. 애니메이션 Logic 을 짤겁니다!

Idle/Run

  • 스테이트 머신을 하나 추가해줍시다.

  • 이름은 Locomotion 으로 해줍시다.

  • Locomotion 을 더블 클릭하여 들어가줍시다. Idle 상태를 만들어줄겁니다.

  • 좌측 하단의 콘텐츠 드로어를 클릭하여 'idle_relaxed' 를 검색하여 블루 프린트 내로 드래그해줍시다.

  • 마찬가지 방식으로 'jog_fwd' 를 검색하여 블루 프린트 내로 드래그해줍시다.
    • jog_fwd 가 여러 개 있는니, 캐릭터를 잘 보고 선택해주세요~

Idle -> Run

  • 빨간색 박스 속 아이콘을 더블 클릭합시다.
    • 상태가 변할 조건을 정해줄겁니다.

  • 간단합니다. Speed 가 0보다 클 때 Idle 에서 Run 상태로 변하게 됩니다.

Run -> Idle

  • 더블 클릭해줍시다~

  • 마찬가지로 간단합니다. Speed 가 0이 되면 Run 에서 Idle 로 바뀝니다.

  • 끝입니다. 다시 AnimGraph 로 돌아와 Locomotion 과 최종 애니메이션 포즈를 이어주면 됩니다.

EnemyBP 에서 EnemyAnimBP 연결하기

  • 다시 EnemyBP 로 돌아와서, '메시 컴포넌트' - 애니메이션 - 애님 클래스를 EnemyAnimBP 로 설정해줍시다.

  • 그리고 뷰포트(플레이 실행 창)에 EnemyBP 를 배치합시다. 그리고 플레이해주면..

  • 잘 작동하는 것을 확인하실 수 있습니다!

EnemyAIController

  • 플레이어가 직접 컨트롤하는 PlayerBP 와 달리, EnemyBP 는 AIController 를 빙의시켜 주어야합니다.

    • 꼭 이런 방식이 아니어도 되지만, 보편적인 방식입니다.
  • Enemy 폴더에서 블루 프린트 클래스를 생성해줍시다.

  • 'aicontroller' 를 검색하여 선택해줍시다. 이름은 EnemyAIController 로 합시다.

EnemyBP 에서 EnemyAIController 할당

  • EnemyAIController 를 만들자마자 갑작스럽긴 하지만, EnemyBP 를 다시 열어봅시다.

  • 그리고 좌측 상단의 컴포넌트에서 'EnemyBP(셀프)'를 클릭하고 우측의 디테일 탭의 '폰' - 'AI 컨트롤러 클래스' 를 EnemyAIController 로 바꿔줍시다.

  • 이로써 EnemyAIController 를 할당시켜주었습니다. 다시 EnemyAIController 돌아갑시다.

다시, EnemyAIController

  • 생성된 EnemyAIController 를 열어, 이벤트 그래프로 갑시다.

  • 틱 이벤트와 'run behavior tree' 라는 노드를 이어줍시다. 이 노드의 'BTAsset' 항목을 지정해주어야 하는데, 우리는 BTAsset 이 없습니다. 그런데 BT 가 무엇일까요?
    • 바로 행동 트리(Behavior Tree)입니다.

Behavior Tree

  • 조금 생소하실 수도 있겠습니다. Behavior Tree 란, 쉽게 설명하여 AI 가 어떤 행동을, 어떤 상황에 할 것인가를 담고 있는 Tree 입니다.

    • 여기서 Tree 라는 자료 구조를 사용하기 때문에 Behavior 뒤에 Tree 가 붙습니다. 말 그대로 행동(Behavior)을 담은 Tree 입니다.
  • Enemy 폴더로 돌아와, AI 라는 이름의 폴더를 하나 만들어줍시다.

    • 여기에 AI 에 관련된 것을 모두 넣을 것입니다.

  • AI 폴더 내에서 빈공간에 우클릭하여, '인공지능' - '비헤이비어 트리' 를 생성해줍시다.
    • 이름은 EnemyBT 로 합시다.

  • BT 에 대한 더 자세한 내용은 뒤에 설명하겠습니다. 일단 넘어갑시다!

Black Board

  • Behavior Tree 와 뗄 수 없는 관계인 Black Board 입니다. BB 는 BT 에 사용될 여러 Key(= 사용자 지정 변수)값들을 담고 있습니다.

  • 다시 AI 폴더로 돌아와, '인공지능' - '블랙보드' 를 생성해줍시다.

    • 이름은 EnemyBB 로 합시다.

다시, EnemyAIController

  • 자, 아까 'BTAsset' 항목을 지정해주려고 했으나, BT 가 존재하지 않아 실패했었습니다. 이제는 BT 를 생성하였으므로 가능합니다.

  • EnemyBT 를 선택해줍시다!

  • 이제 EnemyAIController 에서 할 일은 끝났습니다. EnemyBT 를 열어봅시다.

EnemyBT (+EnemyBB)

  • 우측 디테일 탭에 BehaviorTree - 블랙보드 에셋에 EnemyBB 가 할당되어 있는 것을 보실 수 있습니다.
    • 현재는 BT 와 BB 가 각각 하나이기 때문에 자동으로 할당이 되었는데, 한 쌍이 아닐 때는 직접 알맞는 BB 를 할당해 주어야합니다.

  • 이제 AI 폴더로 가서 EnemyBB 를 열 필요 없이, 우측 상단에 '블랙 보드'를 클릭하면 EnemyBB 가 열립니다.

  • 본격적으로 행동 트리의 '행동' 부분 Logic 을 작성하기 전에, 다시 한 번 전체적인 구조를 정리하겠습니다.

  1. EnemyAIController 할당
    • 별도의 컨트롤러가 없는 Enemy 를 컨트롤 해줄 AIController 생성 후 할당
  2. EnemyAIController 에서 Behavior Tree 실행
  3. BT 에 작성해둔 Logic 대로 행동
    • 아직 작성하지 않았지만, 여기에 작성해둔 Logic 대로 행동합니다.
  • 정리가 되셨나요? 만약 정리가 되셨다면 이제 BT 를 작성하는 일밖에 남지 않았다는 사실을 아실겁니다. 작성해봅시다!
    • 정리가 되지 않았다면, 몇 번 더 읽어보시길 권장합니다!

Behavior Tree Basic

  • 놀랍게도 이번 주차의 본론은 지금부터입니다. 이제 BT 의 요소를 하나하나 알아볼겁니다.
    • 전부 다는 아니고, 우리의 AI 를 구현하는데 필요한 만큼만요. (사실 거의 전부긴 합니다..ㅎㅎ)

Root

  • BT 의 시작점으로 BB 의 데이터를 기반으로 합니다.
    • 루트, 말그대로 뿌리같은 존재입니다. 시작점이라고 이해하시면 충분합니다.

Sequence

  • BT 의 빈공간을 우클릭 해보시면 Composites/Tasks 두 항목을 생성할 수 있는 것을 확인할 수 있습니다.

  • Sequence 는 이 중 Composites 에 해당합니다.

  • 자식 노드를 왼쪽에서 오른쪽으로 실행하며, 실행 중인 자식 노드가 성공하면 그 다음 노드를 실행하고 실패하면 실행하지 않습니다.
    • 여기서 자식 노드란, 부모 노드의 하위에 있는 노드를 뜻합니다.

  • 위 그림에서 D, E 가 자식 노드입니다. 생소하신 분들은 자료 구조에서 배우시게 될겁니다!

  • Sequence 를 한 마디로 설명하면, '실패할 때까지 해라!' 입니다.

Selector

  • Sequence 와 마찬가지로 Composites 항목에 해당합니다.

  • 자식 노드를 왼쪽에서 오른쪽으로 실행하며, 실행 중인 자식 노드가 실패하면 그 다음 노드를 실행하고 성공하면 실행하지 않습니다.

  • 마찬가지로, Selector 를 한 마디로 설명하면, '성공할 때까지 해라!' 입니다.

Tasks

  • 앞서 살펴봤던 Composites 외의 항목인 Tasks 입니다. 이는 우리가 흔히 Function 이라고 표현하는 것과 역할이 매우 비슷합니다.
    • 아직 감이 잡히시지 않으셔도 괜찮습니다. 이후 BT 의 Logic 을 작성하실 때 감이 오실겁니다!

Decorator

  • Composites 을 우클릭하면 Decorator 를 추가할 수 있습니다.

  • Decorator 는 '조건문' 이라고 명확하게 표현할 수 있을 것 같습니다.

    • 이를 통해 특정 조건을 만족하면 특정 행동을 하게끔 만들 수 있습니다.
  • 우리가 사용할 것은 이 정도입니다! 이외에도 Simple Parallel, Service 등이 있지만 당장은 사용하지 않아도 됩니다.

BTT 생성

  • Behavior Tree Task 의 약자입니다. 위에서 설명한 Task 에 해당합니다.

    • Function 과 기능이 유사하다고 하였습니다. 함수를 작성하는 느낌으로 만들어봅시다.
  • AI 폴더로 돌아와서, 블루 프린트 클래스를 생성해줍시다.

  • BTT 라고 검색하여, BTTask_BlueprintBase 를 선택해줍시다.
    • 처음 만들 Task 이름은 MoveToPlayer 입니다.

MoveToPlayer

  • 생성한 MoveToPlayer 를 열어봅시다. 이벤트 그래프를 작성할겁니다.

  • 눈치채셨을 수도 있지만, 이는 Player 에게 다가가기 위한 Task 입니다.

  • 잘 실행되는지 확인해보기 위해 간단한 BT 를 작성해봅시다.

  • 앞선 내용을 잘 이해하셨다면, BT 가 실행되면 Enemy 가 따라오다가 잠시 멈추고(Wait) 다시 따라오는 것을 반복할 것이라고 예측할 수 있습니다.

  • 그런데 플레이를 해보면, 움직이지 않습니다. 왜일까요?

  • 네비게이션 메시를 깔아주지 않아서 그렇습니다. 아래 사진과 같이 NavMeshBoundsVolume 을 생성해줍시다.

  • NavMeshBoundsVolume 의 크기를 키우고, 위치를 잘 조절하여 바닥을 전부 포함하도록 해줍시다.
    • 참고로 P 를 누르면 네비게이션 메시가 잘 설치되었는지를 확인할 수 있습니다. 아래 그림의 초록색 부분이 AI 가 걸어다닐 수 있는 공간입니다.

  • 실행해보면, 잘 움직이는 것을 확인할 수 있습니다. 근데 조금 빠른 것 같으니 속도를 조절해줍시다!

최대 걷기 속도 조정

  • EnemyBP 를 열고, '캐릭터 무브먼트' 컴포넌트 - 캐릭터 무브먼트: 걷기 - 최대 걷기 속도 를 300 으로 바꿔줍시다.

  • 이제 다시 플레이해봅시다.

  • 적당하네요~

SetDistance

  • 그런데 Enemy 가 너무 시도 때도 없이 따라옵니다. 따라서 일정 거리 내에 들어왔을 때에만 따라오도록 하고 싶습니다.

    • Decorator 가 쓰이겠구나~ 라고 생각하셨다면 베리 굳입니다~
  • 우선은 Enemy 와 Player 사이의 거리를 측정하는 용도의 Task 를 만들겁니다.

    • 이것이 바로 SetDistance 의 용도입니다.
  • 앞서 했던 것처럼, AI 폴더로 돌아와서, 블루 프린트 클래스를 생성해준 뒤, BTT 라고 검색하여 BTTask_BlueprintBase 를 선택해줍시다.

    • Task 이름은 SetDistance 입니다. 생성한 뒤 바로 열어줍시다.

변수 생성

  • 변수를 하나 생성해줍니다.
    • Distance(블랙 보드 키 선택 툴) : 블랙 보드에 있는 키를 연결하기 위한 변수입니다. 키에 float 값을 전달합니다. (Enemy 와 Player 간의 Distance)

  • 중요한게 하나 더 있습니다. Distance 의 오른쪽 디테일 창에서, 인스턴트 편집가능을 체크해주어야 합니다.
    • 이걸 체크해야 블랙 보드에서 Key 와 연결하기 수월해집니다.

다시, SetDistance

  • 이 Task 는 이게 끝입니다. 간단하죠~

블랙 보드 Key 와 연결하기

  • 우선, 블랙 보드에서 Distance 라는 Key 를 만들어줍시다.

  • 타입은 플로트, 이름은 Distance 라고 해줍시다.

  • BT 로 돌아와서 Distance Task 를 생성한 뒤, 이를 클릭하여 디테일 - 디폴트 - Distance 를 Distance 로 바꿔줍니다.

    • SelfActor 로 설정되어 있을겁니다.

  • 연결을 완료했습니다! 이제 또 한 번 간단한 BT 를 통해 잘 작동하는지 확인해봅시다.

조건에 따라 움직이는 AI

  • 다음과 같은 간단한 BT 를 작성했습니다.

  • 이제 조건을 넣어줄 차례입니다. Decorator 를 사용합시다.

Decorator 설정

  • 우선 MoveToPlayer 노드를 우클릭하여, '데코레이터 추가' - Blackboard 를 선택해줍니다.

  • 그 뒤, 파란색 부분의 Decorator 를 클릭하여 디테일 탭에서 몇 가지 설정을 바꿔줍니다.
    • 블랙보드 키 : Distance 로 설정
    • 키 쿼리 : Is Less Than 으로 설정
    • 키 값 : 500 으로 설정

  • 같은 방식으로 왼쪽의 Wait 노드도 진행해줍시다.
    • 다만 키 쿼리를 Is Greater Than or Equal To 로 설정해주어야합니다.

  • 이렇게 완성된 BT 는, Enemy 와 Player 사이의 거리가 500 미만일 때에만 움직인다고 해석할 수 있습니다.

  • 플레이 해봅시다!

  • 조건에 따라 잘 작동하네요.

  • 여기까지 2주차 Part.1 - AI Basic 이었습니다. 다음 포스팅은 2주차 Part.2 - AI Application 입니다~

profile
이사감 -> bit.ly/KunHo_Heo

0개의 댓글