[이득우 언리얼 C++] 12. AI 컨트롤러와 비헤이비어 트리

    💻 Code : https://github.com/tedison7/ArenaBattle

    AIController와 내비게이션 시스템

    플레이어가 조종하지 않는 캐릭터를 NPC(Non Player Character)라고 한다. 드래그하여 배치한 ABCharacter 액터에 인공지능을 추가해 플레이어를 공격할 수 있도록 해보자. AIController를 상속받는 ABAIController 클래스를 생성하였다. 그리고 ABCharacter가 ABAIController를 사용하도록 설정한다.

    왜인지 모르겠지만 현재 레벨을 step3 이름의 다른 레벨로 저장하였고, NavMeshBoundsVolume 을 배치하였다. 배치후 뷰포트에서 P 키를 눌러보면 녹색의 네비메시 영역을 확인할 수 있다. 네비메시를 생성한 이유는 네비메시를 통해 AI가 길찾기를 할 수 있기 때문이다.

    책에서는 NavigationSystem을 사용했지만 현재는 4.27버전을 사용하고 있기에 NavigationSystemV1으로 변경을 Possess 함수를 OnPossess 함수로 변경하여 구현하였다.

    빌드후 실행을 해보면 배치한 폰이 3초마다 랜덤한 좌표로 이동하는것을 확인 할수 있다.

    비헤이비어 트리 시스템

    언리얼 엔진에서 제공하는 비헤이비어 트리 모델을 통해 행동 패턴을 체계적으로 설계할 수 있다. AI 폴더안에 BT_ABCharacter라는 비헤이비어 트리 애셋과 BB_ABCharacter 라는 블랙보드 애셋을 생성하였다.

    • 블랙보드 : 인공지능의 판단에 사용하는 데이터의 집합을 의미
    • 비헤이비어 트리 : 블랙보드 데이터에 기반해 설계한 트리의 정보를 저장한 애셋 에디터에서는 트리를 시각화 하여 편집할수 있는 기능을 제공한다.

    인공지능 기능을 사용하기 위해 Build.cs 파일에 AIModule 모듈을 추가하였다. 그리고 ABAIController 클래스의 기존의 코드를 삭제하고 비헤이비어 트리를 가지고 동작할수 있도록 다음과 같이 작성하였다.

    컴파일하여 실행해보면 비헤이비어 트리를 더블클릭하여 비헤이비어 트리가 어떻게 동작하는지 로직 흐름을 살펴볼 수 있다.

    이제 코드로 구현한 임의의 위치로 순찰하는 기능을 비헤이비어 트리로 구현해보자. 블랙보드에 HomePos와 PatrolPos이름의 Vector타입 키를 추가하고 HomePos 키 값이 전달 될 수 있도록 코드를 작성하였다.

    이제 PatrolPos 데이터 생성을 위해 BTTaskNode를 상속받는 BTTAsk_FindPatrolPos 이름의 클래스를 생성한다. Build.cs 파일에서 GamePlayTasks 라는 모듈을 추가해야 컴파일에 성공할 수 있다. 비헤이비어 트리는 태스크를 실행할 때 태스크 클래스의 ExecuteTask 라는 멤버함수를 실행한다. ExecuteTask함수는 다음 4가지중 하나의 값을 반환해야한다.

    • Aborted : 태스크 실행 중에 중단
    • Failed : 태스크에 실패
    • Succeeded : 태스크 성공
    • InProgress : 태스크 계속 수행 중

    컴파일후 비헤이비어 트리 애셋에서 정찰 로직을 완성하고 테스트 해보면 5초마다 캐릭터가 랜덤한 위치로 이동하는 것을 확인 할 수 있다.

    NPC의 추격 기능 구현

    이제는 NPC가 정찰 중에 플레이어를 발견하면 플레이어를 추격하도록 해보자 NPC가 플레이어를 발견할 때 플레이어의 정보를 블랙보드에 저장하기 위해 Object타입으로 Target변수를 생성하고 Base Class를 ABCharacter로 지정하였다.

    그리고 비헤이비어 트리에서는 Target을 향해 이동하도록 다음과 같이 트리 설계를 확장하였다.

    새로운 서비스 시작을 위해 BTService를 상속받는 BTService_Detect 클래스를 생성하였다. 주위를 탐지하는 기능을 코드로 작성해보자.

    다음으로 탐지 영역 내의 캐릭터를 감지하면 그중에서 플레이어 캐릭터를 추려낸다.

    컴파일 후 실행해보면 NPC가 플레이어를 따라다니는 것을 확인 할 수 있다.

    그러나 NPC의 이동시 회전이 부자연스럽다. NPC를 위한 ControlMode를 추가하고 NPC용 캐릭터 무브먼트를 설정해보자.

     

    그리고 비헤이비어 트리도 데코레이터 노드를 추가하여 정찰중에도 플레이어를 감지할경우 바로 플레이어를 추격할 수 있도록 수정하였다. 이후 플레이 테스트를 해보면 NPC가 적절하게 추격해오는 모습을 볼 수 있다.

    NPC의 공격

    이제는 추격을 완료하면 공격하는 기능을 추가해보자 공격가능한 범위에 있는지 확인하는 데코레이터 클래스를 BTDecorator_IsInAttackRange 이름으로 생성한다.

    컴파일을 하여 완성된 데코레이터를 비헤이비어 트리에 다음과 같이 부착해놓자

    그러면 NPC가 플레이어에게 다가와 멈추고 있는 모습을 확인 할 수 있다. 이제 BTTaskNode를 상속받는 BTTask_Attack 클래스를 생성하여 플레이어를 공격하도록 해보자

    위와같이 코드를 작성하면 NPC가 가까이 다가갔을때 공격을 하지만 근접에서 NPC 주변으로 돌 경우 NPC는 같은 방향만 공격하고 있다. 캐릭터의 방향도 따라갈수 있도록 BTTaskNode를 상송받는 BTTAsk_TurnToTarget 클래스를 생성하자.

    코드작성이 완료되면 비헤이비어 트리에서 공격에 사용된 퀀스 컴포짓을 심플 패러럴 컴포짓으로 대체하고 캐릭터의 공격을 메인 태스크로 회전을 보조 태스크로 지정한다.

    플레이후 확인해보면 캐릭터의 방향을 바라보며 공격하는 것을 확인할 수 있다.

    요약

    • AIController의 구조 이해
    • 네비게이션을 이용한 캐릭터 이동
    • 비헤이비어 트리 시스템 구조와 노드들의 기능 파악
    반응형

    댓글

    Designed by JB FACTORY