언리얼 엔진 시작하기 8

2017. 1. 24. 07:55기술/언리얼 스터디

반응형

몬스터 AI를 구현하기 위해서 비헤이비어 트리를 분석해 보도록 하겠습니다.

이미 언리얼 문서에 다 나와있는 내용이지만 이 글은 참고에 조금이나마 도움이 되셨으면 합니다.


사실 AI 컨트롤러가 없어도 그냥 코딩으로 만들어 주어도 무관합니다. 비헤이비어 트리는 이런 AI를 하나의 엔진 기능으로 조금 더 편리하게 구조적으로 만들어준 것인데 사용하려면 그 엔진 기능을 익혀야 하죠.


이글은 프로그래머를 대상으로 합니다. 디자이너가 클라이언트 프로그래머 역할을 하는 것은 프로그래머가 그래픽을 다룬다는 것과 비슷합니다. 뭐 모든 것을 다 할 수 있는 분도 있을 수 있겠지만 극히 드물겠죠. 그러므로 프로그래머를 대상으로 글을 작성하겠습니다. AI를 만들어 주기 위해서는 프로그래머적인 사고가 필요합니다.


1. 준비물

AI를 만들어주기 위한 준비물은 다음과 같습니다.

AgroCheck, CloseEnough, RapidMoveTo는 엔진 사용자( 프로그래머 )가 만들어준 하나의 상속형 클래스라고 생각하면 됩니다. 이 클래스 들이 AI에서 하나의 행동이 될 것입니다.


AI_Character는 보여지는 것(Mesh)와 Follower_AI_CON을 연결해주는 역할을 합니다. 그리고 AI 캐릭터의 CharacterMovement 구성요소(Component)에 NavMovement 속성을 설정해 주는 것이 중요합니다. AI 캐릭터는 네비 메시를 타고 다니기 때문에 이를 설정해 주어야 하는 것이죠.


Follower_AI_CON은 AI의 컨트롤러 입니다. 키보드로 조작(Control) 하는 것이 아니라 블랙보드를 셋팅하고 비헤이비어 트리를 실행시켜 주는 역할을 합니다.


FollowerBlackBoard는 위에서도 말씀 드렸듯이 비헤이비어 트리에서 사용하기 위해 변수와 같은 '키'들을 써 놓는 곳입니다. 다른 AgroCheck이런 클래스에서 여기에 접근하여 변수에 값을 연결해 두어야 합니다.


FollowerBT는 인공지능 AI의 '뇌'라고 생각하면 될거 같습니다. 어떻게 행동하는지 결정하고 트리 모양을 하고 있습니다.


위 클래스들의 관계도를 그려보면 다음과 같을 것입니다.



2. 흐름 분석

기존내용을 알고 있어야 그 위에 프로그래밍이 가능합니다. 그러므로 분석을 해 보도록 하겠습니다.


AI는 Follower_AI_CON에서 시작합니다.

게임이 시작되면 BeginPlay 이벤트가 발생합니다. 블랙보드( FollowerBlackBoard )를 사용할 것을 알리고 블랙보드의 HomeLocation이라는 키 값에 액터의 위치를 저장해 둡니다. 그다음 비헤이비어 트리( FollowerBT )를 실행시킵니다.


그럼 블랙보드의 '키'를 살펴보겠습니다.


따라갈 객체( TargetToFollow Object ), 시작위치( HomeLocation ), 따라갈 객체의 위치( TargetLocation ), AI 객체( SelfActor ) 키가 있습니다. 이 키들은 전부 비헤이비어 트리에서 사용할 변수값들 입니다.


비헤이비어 트리 실행

셀렉터는 가지중에서 왼쪽부터 실행이 되며 한 가지의 실행이 성공한다면 그 행동에 머물러 있습니다. 가장 처음으로 실행되는 것은 AgroCheck라는 서비스 입니다.

tick every가 0.5초로 설정되어 있는 것은 이 서비스를 0.5초에 한 번씩 실행하겠다는 것입니다.

그럼 AgroCheck 서비스 블루프린트를 열어 보겠습니다.


AgroCheck 서비스

쫓아갈 객체 찾기


일단은 저 열거형(enum) 배열이 중요합니다. 변수 옆에 큐브 모양의 아이콘을 클릭해 주면 배열로 바뀌고 값을 하나 추가해서 Pawn을 설정해 주어야 합니다.

AI_CON_Ref는 우리가 만들어 놓은 AI 컨트롤러 객체의 참조입니다.


Receive Tick 이벤트는 0.5초마다 발생합니다. 비헤이비어 트리에서 설정이 가능하였죠. AI_CON_Ref가 없으면(null) 상위 Actor를 Follower_AI_CON으로 형변환하여 변수에 연결합니다. 


AI_CON_Ref 변수 설정이 끝났으면 모든 적 객체( Mixamo Character )를 얻습니다. Out Actors 배열에 저장해 둡니다. 그 다음 라인을 그려서 충돌검사를 하는 MultiSphereTraceForObjects 함수를 실행 시킵니다.

이 함수에서는 선을 그을 시작지점과 끝지점 두 위치 벡터가 필요합니다. 범위는 1500이고 ObjectType은 Pawn 입니다. 최적화를 위해서인지 같은 적들 객체는 충돌검사에서 제외( Actors to Ignore )합니다. 자신도 제외( Ignore Self )합니다.

이 함수가 실행이 되면 이 선에 충돌된 객체가 Out Hits 배열에 담깁니다.


배열을 Foreach문으로 순회합니다. 하나의 요소마다 Line Trace By Channel 함수를 실행하는데 채널에 의한 충돌여부를 검사합니다. 두 벡터 설정과 제외되는 객체들( Actors to Ignore ) 설정은 같습니다. Break hit Result 함수는 여기에서 별다른 큰 의미는 없는거 같습니다. Hit Actor를 사용합니다.


두 액터가 같다면 블랙보드의 TargetToFollow 키에 값을 할당하고 TargetLocation에 찾아낸 액터의 위치를 할당합니다.

두 액터가 같지 않으면 TargetToFollow 키를 null로 할당합니다.


여기까지 쫓아갈 객체를 찾아내었습니다.



셀레터는 왼쪽부터 실행하고 그 실행이 성공이면 그 아래 노드를 실행합니다.

TargetToFollow가 있으면( is Set ) 왼쪽게 실행되고 없으면( is NotSet ) 오른쪽이 실행됩니다.

있을 경우 CloseEnough 데코레이터가 실행됩니다.


CloseEnough 데코레이터

내용은 간단합니다. TargetToFollow의 위치와 AI 캐릭터의 위치의 길이가 허용거리( Acceptable Distance )보다 큰지 여부( bool )를 반환합니다. 위 그림에서 허용거리는 100으로 설정되어 있습니다. CloseEnough의 Acceptable Distance float 변수를 편집가능 상태로 해 두었기 때문에 비헤이비어 트리에서도 편집이 가능합니다.


TargetToFollow의 위치와 AI 캐릭터의 위치의 차이가 100 보다 크면 true를 반환하고 Rapid Move To 테스크를 실행하게 됩니다.



RapidMoveTo 테스크

플레이어쪽으로 이동합니다.


이 부분은 위에서 설명드렸습니다. 반복되는 블루 프린트 처리 방법에 대해서 알아두어야 겠습니다. ( 복사 붙여넣기가 가능합니다. )


중요한건 AI Move To 함수인데 AI 객체와 타겟 객체를 설정해 주고 가능한 반경을 50으로 설정해 준 다음 Finish Execute를 호출해서 성공( Success ) 여부를 알립니다.


블랙보드의 TargetToFollow가 null이고 HomeLocation 반경 안에 있고 TargetLocation이 설정되어 있다면 "아래의 시퀀스를 실행하라"라는 의미 입니다.

일단은 플레이어를 마지막으로 찾은 위치 TargetLocation까지 이동하고 2.5초 대기 후 다시 기존 위치 HomeLocation으로 이동하라 입니다. 디버깅을 해 보면 알 수 있습니다. 이 부분이 반복되므로 AI 플레이어는 왔다갔다를 반복하는 것을 확인할 수 있습니다.


3. 간단한 전투 구현

피격 모션에서 이동이 가능한 점이랑 약간 버그가 있는점을 깔끔하게 수정해야 합니다.

그리고 블루프린트 정리와 여기까지 작업한 내용도 조금 정리해서 문서로 만들어둘 필요가 있겠습니다.


이후에 구현해야 할 내용은 인게임 UI, 캐릭터 스킬 추가, 적 AI 추가, 간단한 레벨 디자인 정도가 있겠습니다.

장비 시스템을 추가한다면 공격속도, 이동속도, 공격력등의 능력치를 올릴 수 있겠습니다.

다음으로 네트워킹이 있겠네요. 네트워킹 되고 길드기능 추가하면 친구들과 여럿이서 전투하는 것도 구현해야 하고 보스 레이드라든가 콘텐츠를 추가할 수 있습니다. 보통 콘텐츠를 즐기는 이유는 좋은 장비 아이템을 얻기 위함이며 자기 캐릭터 뽐내기, 등수 올리기등 여러가지 목표가 있겠습니다.


보스 레이드 구현하기를 잠깐 설명해 보겠습니다.

위에서 간단한 전투가 구현이 되었습니다. 고블린이 보스라고 하면 AI를 조금 추가하고 HP를 늘립니다. 그리고 사냥시 아이템 드랍을 한다고 했을 때, 보스는 조금 더 좋은 아이템을 드랍하도록 프로그래밍 하면 됩니다.


프로젝트 규모에 따라 개발인원이 늘어날 것입니다.


일단 언리얼 엔진 공부를 계속 하도록 하겠습니다.


참고할만한 사이트


2017년 2월 3일 런처를 켜 보니까 좋은 튜토리얼이 하나 더 있네요.


위 내용은 무슨 내용인지 잠깐 살펴보았습니다.


4. 지형 추가하기

일단 맵이 너무 좁은거 같아서 지형( Landscape )을 하나 만들어 주었습니다. ContentExample에서 모든 폴더를 이주하면 사용할 수 있는 자원( Asset )이 늘어나서 좋은거 같습니다. 그데로 이주해 줬더니 자료들이 여기저기 섞여서 좋지 않은거 같습니다.


인스턴싱된 메시를 사용하여 풀이나 돌로 지형을 꾸며주면 조금 더 이쁜 맵이 되겠습니다.


맵을 그려놓고 보면 캐릭터에 그림자가 너무 짙게 적용되는 것을 볼 수 있는데 Sky Light를 하나 추가해 주면 됩니다.



정리 - 지금까지 실행하거나 만들어본 언리얼 프로젝트 입니다.

 QuickStart

가장 처음에 해봤던 프로젝트로 C++ 코드를 간단하게 작성 하는 방법에 대해 익혔습니다.

 BatteryCollector 

두번째로 C++ 코드를 작성하면서 베터리들이 떨어지고 그것을 습득하면 캐릭터의 파워가 올라가는 프로젝트였습니다. 파티클과 UI에 대해서도 전체적으로 알 수 있었던 프로젝트 입니다. 

 ThirdPersonProject

캐릭터 FBX 임포트, 달리기 상체만 애니메이션 하기, 발바닥에 파티클을 입혀볼 수 있었던 프로젝트 입니다.

 ContentExamples

그저 리소스를 이주해서 사용하기 위한 프로젝트 

 StageyGame 

디펜스 게임이라고 하는데 플레이만 한 번 해 보았습니다. 

 CouchKnights 

캐릭터 공격 관련해서 알아보려고 설치한 프로젝트인데 내부가 조금 복잡합니다.

 StudyBluePrint

캐릭터가 일정 영역 발판을 밟으면 점프하는 프로젝트로 블루프린트에 대해 처음에 알아보기 위해 해보았던 프로젝트 입니다. 

 StudyBPCast

블루프린트 캐스트에 대해서 알아보기 위해 해 보았던 프로젝트 입니다. 총알 발사와 이펙트를 다루어 볼 수 있었던 프로젝트 입니다.

 StudyNavMesh

간단한 지형 만들기와 네비게이션 메쉬를 만들어 볼 수 있었던 프로젝트 입니다.

 StudyTopDown_BP

몬스터AI를 진행해 볼 수 있었던 프로젝트 입니다. 맵 오브젝트에 재질을 입혀보았습니다.

 StudyTopDownCPP

블루프린트와 CPP가 어떻게 다른지 알아보려고 만든 프로젝트 입니다.

 UnrealMatch3

블럭게임을 알아보기 위해 설치했던 프로젝트입니다. 모바일 프로젝트에 대해서 아직 분석할게 많이 남아있습니다. 블럭 모바일 게임을 진행하지 않는다면 현재 딱히 분석할 필요는 없지만 게임 말고 모바일 기능들을 추가해야 할 때 분석할 필요가 있는 프로젝트

 GameWorld

3인칭 전투를 개발해 본 프로젝트로 FBX 캐릭터 임포트, AI를 구현하였습니다.







반응형