본문 바로가기

개발/내일배움캠프

02/05 AI블루프린트 구성해보기 & 퀘스트

AI행동설정을 위한 준비작업들
비헤이비어 트리(Behavior Tree) 와 구성요소들(노드, 데코레이터, 서비스)

 

두뇌 역활을 하는 블랙보드(BlackBoard)

 

비헤이비어 트리의 구성요소

Root : 결정트리의 시작점, 따로 기능은 없음

Composites(컴포짓) : 분기의 루트와 분기의 실행방식에 대한 기본 규칙을 정의함

  • Selector : 왼쪽에서부터 오른쪽으로 자손을 실행함, 하나의 자손이라도 성공하면 셀렉터는 성공.
  • Sequence : 왼쪽에서부터 오른쪽으로 실행함, 모든 자손이 성공해야 시퀀스에 성공함
  • Simple Parallel : 메인 테스크 하나와 백그라운드 트리(보조 트리)를 실행. 모드에 따라 백그라운드 트리 작업을 대기/중단함.

Task : 실제 행동을 정의하는 노드

Decorator : 조건식, 다른 노드에 부착되어 노드나 트리의 실행여부를 결정함.

Service : 컴포짓 또는 태스크 노드에 부착되어, 실행중인 동안 주기적으로 실행되고 주로 블랙보드의 확인과 업데이트에 사용됨.

 

플레이어를 찿는 AI를 만들기위한 비헤이비어트리

해볼내용은 위 행동트리의 내용을 작성하는것.

 

왼쪽 분기는 플레이어를 찾는 데코레이터, 찾았다면 TargetPosition으로 이동하게끔 하는 태스크를 실행하도록,

오른쪽 분기는 무작위 지점을 찾고 TargetPosition으로 이동하도록 하는 태스크로 구성되어있음.

 

사용된 Move To 태스크의 공식문서 정의는 다음과 같음.

Move To 태스크는 캐릭터 무브먼트(Character Movement) 컴포넌트를 갖춘 폰이 내비메시를 사용하여 벡터 블랙보드 키로 이동하도록 합니다.

-> 내비메시와 벡터 블랙보드 키 값이 필요함.

 

내비메시에 대한 정의는 다음 문서

https://dev.epicgames.com/documentation/ko-kr/unreal-engine/basic-navigation-in-unreal-engine

 

언리얼 엔진의 기본 내비게이션 | 언리얼 엔진 5.7 문서 | Epic Developer Community

이 가이드에서는 언리얼 엔진에서 내비게이션 시스템을 사용하는 방법을 설명합니다.

dev.epicgames.com

AI에게 이동 가능한 경로를 정의해주는 "공간"을 자동으로 만들어주는 객체임.

 

그리고 TargetPosition은 앞서 얘기한 이동목적지가 되는 벡터 블랙보드 키.

 

 

컨텐츠 드로어에서 블랙보드와 비헤이비어 트리를 생성

 

블랙보드에서는 New Key를 누르고 Vector타입의 키 생성. 이름은 TargetPosition

 

비헤이비어 트리를 생성하여 아래처럼 구성하고,

디테일에서(ROOT노드선택 또는 아무노드도 선택되지않은 상태에서) 비헤이비어트리-블랙보드 에셋에 생성한 블랙보드 선택.

왼쪽은 셀렉터 컴포짓 아래에 IsNearPlayer데코레이터와 MoveTo 액션을, 
오른쪽은 FindingRandom서비스에 따라 MoveTo 액션을 실행하도록 만들어짐.

 

두 MoveTo는 벡터 블랙보트 키가 필요하다고 했는데 선택후 디테일에서 지정해주면 됨.

 

데코레이터와 서비스는 블루프린트로 구성.

 

IsNearPlayer데코레이터의 블루프린트 내용

PerformConditionCheck를 통해 시작.
후술할 캐릭터 블루프린트로 Cast하고 캐릭터의 시야를 가져와
Component Overlap Actors를 이용해 시야 내 플레이어 폰이 있는지 확인.

Object Typs는 배열값을 입력받는데 MakeArray에서 Pawn타입으로 지정. 이는 Pawn타입 엑터만 가져오겟다는걸 의미함.

결과 배열에 플레이어 폰이 있는지 확인.

없다면 Return Node False를 통해 실패한것으로.

있다면 블랙보드 키값인 TargetPosition을 찾아낸 플레이어 폰의 로케이션값 벡터로 지정하고 True를 반환함.

 

이후에는 MoveTo가 실행되어 해당위치로 이동할것으로 예상.

 

실패한 경우 오른쪽 노드인 랜덤위치 이동을 실행해볼것.

 

FindingRandom서비스 블루프린트 내용

실행되면, 원래 위치를 중심으로 2000범위 내 랜덤 위치를 가져옴.
GetRandom~~~Radius의 Return Value는 해당 지점이 이동 가능한지의 여부를 반환함.

그러니 True일때만 분기로 이동하여  TargetPosition값을 지정해줌.

 

서비스는 지속적으로 실행되도록 되어있음.

그래서 일정 틱마다 실행하도록 설정을 따로 할 수 있음.

서비스 디테일에는 Interval과 Random Deviation(랜덤 편차) 설정이 있는데
이는 Tick이벤트를 0.4초~0.6초 주기로 발생시키도록 함.

 

그리고 Tick이벤트를 추가로 지정.

틱 이벤트마다 원래 TargetPosition과 현재 위치를 비교하여, 거리가 10미만이라면 True 아니면 False를 지정.

True라면 처음처럼 다시 랜덤 지점으로 이동하도록 TargetPosition을 계산함

그냥 목적지에 다다르면 다른지점으로 이동하도록 하는것임.

 

 

적용은 아직 해보지 않았으나 궁금한점은 Tick이벤트에서 목적지를 계속 변경하면 해당 이벤트가 제대로 끝나는건지 모르겟음...

내일 강의에서 적용해볼때 알아보도록 하고 내용 정리하고 마무리

 


내배캠 퀘스트

캐릭터 Blueprint 생성 및 이동 설정

이전 배운 내용 기반으로 캐릭터 블루프린트 직접 만들고 이동 입력 받아 처리하기.

 

일단 직접 지정해준 과정은 아래와 같은데...

 

Step2까지는 따라서 진행하였으나
Step3내용이 좀 이상함.

 

직접 배울때는 프로젝트 세팅-인풋에서 설정하는게 아닌 

Input Mapping Context와 InputAction에셋을 생성해서 사용하였기 때문에
위 내용이랑 맞지 않는다는 느낌이 있어 배운대로 진행해보도록함.

 

게임모드를 변경하는 방법은 Edit > Project Settings > Maps &  Modes에서 Default GameMode에 +버튼을 이용해 새로 생성후 수정.


MyGameMode이름의 클래스로 생성하고 디테일패널에서 Default Pawn Class를 아까 복사한 MyCharacter로 변경.

이러고 실행하면 사실상 기본 템플릿과 완전히 똑같은 상태임.

캐릭터도 복사본이라 동일하기때문에 WASD움직임과 기본 점프까지 다 구현이 되어있는 상태.

 

퀘스트 내용은 "직접 구현해보기"인데? 이미 기본이동이 모두 구현이되어있음!

뭐라도 다르게 해보기 위해서 늘상 FPS에 있는 Shift를 눌러 걷기 구현을 해봄.

 

구현과정

우선 프로젝트의 게임모드 변경

에디터 상단 Edit-Project Setting-Maps & mode에서 Default GameMode에서 MyGameMode생성,

이후 해당 에셋을 열고 Default Pawn Class를 복사한 MyCharacter로 변경(위 내용과 같음)

!!추가로 프로젝트가 아닌 월드 세팅의 게임모드도 바꿔야함!!

자꾸 캐릭터가 안바뀌어서 고생좀 한 부분인데, 기본템플릿의 게임모드가 레벨-월드세팅에서도 지정이 되어있어서, 

여기서 게임모드 오버라이드를 None으로 하던지 아까만든 MyGameMode로 변경하던지 해야함.

 

 

걷기 구현을 위한 Input Action 추가

바꿀점은 따로 없음, Shift를 눌렀다 아니다만 확인할것이므로 Boolean그대로 쓰기 때문

 

원래 있던 인풋 매핑 컨텍스트를 복사해서 MyIMC로 바꾸고, 내용 추가

트리거 조건에 Pressed, Released를 추가하여 쉬프트 눌렀을때 뗏을때 반응하도록 할 예정.

 

이제 복사본인 MyCharacter의 블루프린트로 이동하여 내용이 추가된 IMC를 사용하도록 지정

Mapping Context를 내가 만든 MyIMC로 변경

 

그리고 IA_Walk이벤트에 반응하는 내용 추가

아까 설정한 트리거 2개 조건일때 발생하고,

ActionValue는 예상대로 누를때 True, 뗄 때 False가 발생함.

캐릭터의 이동속도는 MaxWalkSpeed라는 값으로 제한이 되어있음 기본값은 500, 그러니 걸을때는 절반으로 변경하도록 함.

 

좌쉬프트 여부에 따라 속도를 변경하였으니 실행만 해보면 된다.

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.

잘된다!

이정도면 퀘스트 내용에 부합하지않을까 싶다.

 

 

시행착오 및 느낀점 등

Project Setting에서 게임모드를 변경해도 MyCharacter가 안나오고 원본인 BP_ThirdPersonCharacter가 튀어나왔는데
원인은 게임모드를 참조하는곳이 2곳이었기 때문

플레이중인 레벨에서는 당연하게 현재 레벨이 오버라이드한 게임모드를 씀

이걸 몰라서 몇분 해매다가 초반에 들은강의내용이 불현듯 생각나 확인해보니 여기가 문제여서 변경되지 않았던 것.

 

캐릭터 속도 제어방법을 모름

캐릭터의 속도는 어떻게 알았나 - 가속도, 최대속도 등을 알아내기위한 삽질들....

나중에 알았는데 당연하게도 CharacterMovementComponent에 해당값 다 있음

 

아무튼 속도가 저값에 의해 제어받는걸 알았으니 트리거에 따라 조절할 수 있었음.

 

내용도 복습되고 괜찮은 활동이었던거같다

 

관련 내용검색하면서 또 애매하게 안 사실은 퀘스트 내용인 프로젝트세팅에서 인풋 확인하라는거...

이거 언리얼5 이전에 Enhanced Input어쩌구 없을때 쓰는 방식인거같던데 좀 이상하다

나중에 좀더 알아봐야할듯