본문 바로가기

언리얼 BluePrint 정리

07/18 학습 정리 ( Patrol 구현 )

Patrol 구현

 

잠입 액션게임을 보면 AI들이 플레이어를 찾으려고 왔다갔다 하면서 순찰 하는 모습을 볼수 있는데 그 기능을 구현해보자

Patrol 기능은 경로를 정해 주고 그 경로를 AI가 이동하는 형식이라고 보면된다. 스타나 워크의 패트롤과 동일 경로는 Spline을 이용해 만든다.

 

Spline

 

Spline은 점과 점 사이를 연결한 선들의 집합체로 이동경로에도 사용 할 수 있지만 기찻길이라던가 도로라던가 일정 거리마다 메쉬를 생성 할 때도 사용 가능하다.

 

Actor 클래스를 부모로 하는 BP_PatrolRoute 생성, Spline 컴포넌트 추가, 추가한 Spline을 Root Component로 지정

BP_PatrolRoute를 레벨에 배치하고 우클릭하여 스플라인 포인트를 복제하여 경로를 늘릴 수 있다.

스플라인 포인트 유형을 상수형식으로 하면 직선으로 보인다.

어차피 AI들은 직선으로 이동하기 때문에 커브를 줘도 그 포인트로 이동을 하기에 상수로 하는게 보기 직관적이다.

 

 

레벨에 배치한 PatrolRoute의 포인트를 눌러서 Spline을 확인해보면 내가 누른 지점이 이 경로의 몇 번째 포인트인지 알수있다. Spline은 기본적으로 배치했을 때 0, 1 두개의 포인트가 존재하며 복제를 할때 마다 늘어난다.

 

Closed Loop를 켜고 끄는 체크박스가 있는데 이건 이 경로가 폐곡선인지 개곡선인지를 정해주는 역할이다.

Spline은 지점을 찍어주는 것이지 경로를 정해주는건 사용자 마음이다. 예를들어 아래 사진과 같이 포인트가 4개인 Spline있다고 가정하면 끝 지점에서 그다음 경로를 0번부터 다시 순환하는 방식과 끝 지점에 이전 지점 방향으로 역주행하는 방식이 가능하다.

이런식으로 경로를 폐곡선으로 할지 개곡선으로 할지를 구분하라고 만든 언리얼 자체에서 제공하는 변수인 것이다.


BP_PatrolComponent 생성 및 함수 추가

 

Actor Component 클래스를 부모로 하는 BP_PatrolComponent 생성

 

 

Get Destination : 다음으로 이동할 목적지의 위치를 구하는 함수

Set Index to Next : 다음으로 이동할 목적지의 인덱스값을 정해주는 함수

PatrolRoute : BP_PatrolRoute의 오브젝트 레퍼런스 ( 인스턴스 편집 가능으로 설정 )

Reverse : 진행방향이 역방향인지 정방향인지 알 수 있게 정해주는 Boolean 변수

Index : Spline Point의 번호를 저장할 변수


PatrolRoute가 존재하면 Spline(BP_PatrolRoute의 RootComponent)의 Index번째 지점의 위치값을 Get Location at Spline Point 노드를 이용해서 얻어 리턴시킨다. 이때 Coordinate Space는 Local이 아닌 World를 이용 PatrolRoute가 없으면 원점을 리턴시킨다. 물론 경로가 원점인 경우가 있을수도 있으니 리턴값에 Result 변수를 줘서 원점인 경우도 구분 가능하다.


Get Number of Spline Points : Spline의 포인트의 개수를 리턴시켜주는 노드 (마지막 지점의 Index가 아닌 총 포인트 개수)


BTT_Patrol

 

목적지를 정해주는 기능은 다 만들었으니 그 방향으로 이동하는 태스크를 만들어 비헤이비어 트리에 추가해준다.

 

AI Perception에 플레이어가 감지되지 않았을 경우 TargetActor가 None이라 순찰을 하다가 감지되면 무기 장착후 쫒아와서 공격하고 다시 감지를 벗어나면 무기를 넣고 순찰을 재개한다


 

BP_Enemy에 BP_PatrolComponent를 컴포넌트로 추가

레벨에 배치한 Enemy의 PatrolComponent에 PatrolRoute를 지정하여 Enemy마다 사용할 경로를 정해준다.

 

 

적이 게임플레이시 PatrolRoute에서 시작되게 위치를 세팅.

Construction Script에서는 아직 Route가 레벨에 배치되지않았기에 작동하지 않아 BeginPlay에 넣어준다.

 

같은 Route라도 인덱스를 다르게 줘서 다른 지점에서 시작하게 가능