2019년 5월 31일
언리얼 엔진을 사용해 레이저와 기관총으로 무장한 거대한 고속 차량을 제어하는 AI를 얻는 방법
이 글에서는 언리얼 엔진 4를 활용해 멋진 AI 적을 창조할 수 있는 깔끔한 솔루션을 설명합니다.
200KPH에서 의사 결정을 한다는 것은 어떤 의미가 있을까요?
다크 퓨처(Dark Future)의 AI는 몇 가지 흥미로운 문제를 해결해야 했습니다.
- 먼저 차량이 파편과 다른 차량, 급커브나 협곡 등으로 가득한 고속도로를 이동해야 했습니다.
- 게다가 이 동작은 빠른 속도(이때 빠른 속도는 최대 200KPH(124MPH)를 의미합니다!)로 진행됩니다.
- 또한 이와 동시에 기관총이나 로켓 발사대가 설치되고 지뢰 등을 발사하는 플레이어 조작 차량과 싸워야 했습니다.
- 마지막으로 이 모든 동작은 플레이어가 지루하거나 반복된다고 느끼지 않을 수준에서 전략을 세울 수 있을 정도로 충분히 예상이 가능해야 했습니다.
확실히 벅찬 일입니다!
하지만 이런 문제를 해결하기 전 일단 운전을 할 수 있어야 합니다. 다크 퓨처는 PhysX 차량 시뮬레이션에서 도입한 언리얼 엔진 4의 차량 시뮬레이션 코드를 수정한 버전을 사용하여 차량이 상당히 세밀한 주행 모델을 갖게 되었습니다.
물론 이것은 AI가 아니기 때문에 자세한 내용은 설명하지 않겠지만 게임 내 차량이 실제 차량처럼 스로틀과 스티어링을 구사했다고 말하면 충분할 것입니다.즉 차량은 운전이 가능했습니다. 다행히 이 방법은 어렵지 않았습니다. 스로틀은 -1부터 +1까지의 수치로 스티어링도 마찬가지입니다. 멋지죠.
레이저로 가득한 고속 자동차 제어에 대한 교훈
UE4의 AI가 내장된 내비메시 기능이 우리 차량에 적합하지 않다는 것을 알게 되자 이런 문제를 생각해야만 했습니다. 현장에서 작동하는 캐릭터에게는 아주 효과적이지만 이 시스템을 차량으로 확장하는 것은 이상적이지 않을 것입니다. 따라서 스티어링 동작이 올바르게 작동할 수 있도록 도움이 될 만한 게 필요했습니다.
스티어링 동작은 섬세하지 않은 대량의 경우에 적합하지만 거대한 액터 몇 개가 스티어링 동작을 사용해 충분한 시간 동안 환경을 탐색하는 경우 균열이 발생합니다. 균열이 발생하지 않는다면 해당 동작으로 이루어지는 의사 결정의 컨텍스트를 만들기 위해 여러 동작을 긴밀하게 연결하는 수천 줄의 코드로 구성되었기 때문입니다.
당시 수석 프로그래머인 아비셰크 사기(Abhishek Sagi)는 AAA 레이싱 게임의 놀라운 솔루션을 선보인 앤드루 프레이(Andrew Fray)가 지은 게임 AI 프로(Game AI Pro) 2의 "컨텍스트 스티어링: 매크로 스케일의 행동 기반 스티어링(Context Steering: Behavior-Driven Steering at the Macro Scale)"에서 그 솔루션을 발견했습니다.
컨텍스트 스티어링이 무엇인지 자세히 다루지는 않겠지만 (이 블로그에서 전부 읽을 수 있고 읽어두면 좋기 때문입니다) 간단히 설명해 보겠습니다. 컨텍스트 스티어링은 원칙적으로 여러 동작이 개별적으로 계산을 수행하여 종합적으로 결과를 산출하는 스티어링 동작 구현과 유사합니다. 컨텍스트 스티어링 시스템에서는 각 동작이 결정에 도달해 결과를 산출하는 대신 결정을 내릴 수 있는 상황을 제공하므로 시스템이 최종 결정을 내릴 수 있는 정보가 훨씬 많습니다.
멀티스레딩을 최대한 활용하기
따라서 우리는 프로토타입에 컨텍스트 비헤이비어 시스템(Context Behavior System, CBS)을 적용해 보았습니다. 이를 위해 '고급 차량(Vehicle Advanced)'이라는 템플릿을 사용한 신규 프로젝트를 시작한 뒤 장애물이 있는 자체 지도를 활용한 뒤 차에 스로틀을 설정했습니다.
이후 단일 블루프린트를 사용해 빠르고 단순한 CBS를 작성했습니다. 이 블루프린트는 엄청나게 거대해서 스크린숏 작업을 하기에도 힘들 정도였습니다. 아래 그림은 블록을 피하며 스플라인을 따라 먼 거리의 목표를 쫓는 프로토타입 차량을 보여 줍니다. 이 솔루션에 블루프린트를 활용하면 우리에게 완전히 새로운 영역을 시각화하는 데 도움이 되어 정말 유용했습니다. 결국 이틀 만에 기본 구현 내용을 작성하고 반복할 수 있었습니다.
대단하죠! 이제 우리 차가 스티어링을 할 수 있었기 때문에, 프로토타입 블루프린트를 테스트 프로젝트에서 가져와 다크 퓨처에 임포트한 뒤 차량에 연결하니 문제가 해결되었습니다!
상상되겠지만 이 과정은 엄청나게 비쌉니다. 현실적으로 우리가 렌더링이 무의미할 정도로 시스템의 효율성을 방해하지 않고 레벨에서 CBS를 사용해 작동할 수 있는 차량은 4대가 한계였습니다. 이것으로는 부족했습니다.
그러나 솔루션은 있었습니다. 컨텍스트 스티어링은 컨텍스트를 제공하는 데 필요한 데이터로 구성된 작은 개별 동작을 가지고 있다는 속성 때문에 멀티스레드에 매우 적합합니다. 따라서 UE4의 멀티스레딩 API를 사용하여 각 차량의 데이터 세트가 게임 스레드 내에서 생성되어 작업자 스레드로 오프로드된 뒤 비헤이비어를 통해 데이터를 실행하고 반환된 컨텍스트에 따라 처리하고 최종 스티어링 결과를 계산하여 다시 차량에 전달하는 솔루션을 작성했습니다.
이제 레벨에 20대 또는 심지어 30대의 차량도 쉽게 구현이 가능했습니다. 모든 차량의 코드는 동일했지만 CBS의 비용은 무시할 수 있었죠. 당연하게도 30대의 고도로 세밀한 완전 시뮬레이션 차량을 레벨에서 동시에 구현할 때 발생하는 비용은 피할 수 없었고 해당 장소에서 30대의 적 차량을 상대로 게임을 플레이하는 일도 쉽지 않지만 가끔은 그 원리가 중요하니까요!
CBS를 사용한 비헤이비어 트리 탐색
믿을 수 없을 만큼 어려운 작업을 몇 주 동안 진행한 결과 우리의 AI는... 좌우로 회전이 가능해졌습니다. 대단한 일이었죠!
이제 어디로 가고 싶은지, 누구를 쫓고 싶은지, 어떤 길로 이동하고 싶은지, 누구를 쏠지, 언제 쏠지 등을 결정해야 했습니다. 이때는 UE4의 비헤이비어 트리(Behavior Tree) 시스템을 사용했습니다.
비헤이비어 트리는 AI의 의사 결정을 추진하는 데 널리 사용되는 방법입니다. 멋진 내비게이션 기능을 사용하지 않더라도 비헤이비어 트리 시스템으로는 여전히 우리가 필요한 모든 것 이상이 가능합니다!
이 단계에서 CBS에는 세 종류의 동작이 있습니다.
- 회피, 환경 내에서 피해야 할 물체를 추적합니다.
- 추적, 주어진 지점을 향해 이동합니다.
- 도로 이동, 말 그대로의 동작을 수행합니다.
AI가 수행할 수 있는 여러 맞춤형 블루프린트 작업을 작성하는 과정에서 여러 곳에 CBS를 활용할 수 있게 되었습니다.
전투 중이 아닌 경우 추적을 비활성화하고 도로 이동에 이상적인 목표 도로를 제공하여 AI가 회피의 추적 길이를 늘려장애물에 '주의'하도록 합니다. 전투 중에는 추적을 활성화하여 대상 차량의 위치를 제공한 뒤 적절한 시점에 무기를 발사하기 위한 논리로 진행합니다.
우리는 또한 인바이런먼트 쿼리 시스템 (Environment Query System, EQS)을 활용하여 게임 환경을 쿼리하고 결과에 대한 일련의 테스트를 실행했습니다. 일반적으로 이 시스템은 내비 포인트 세트를 쿼리하는 내비게이션 시스템과 협력하여 거리나 시선과 같은 항목을 테스트합니다. 우리는 특정 팀(플레이어, 적 AI, 민간 AI 등)에 대한 차량을 찾고 근접도 및 방향에 따라 점수를 매기는 맞춤형 쿼리 생성기를 작성했습니다.
단일 결과를 찾거나 모든 결과를 반환하기 위해 EQS 쿼리를 실행할 수 있으므로 이 쿼리는 단순한 적 탐지 외에도 이상적인 대상 선택 역할을 할 수 있습니다. EQS 쿼리가 이보다 더 대단한 것은 시간적으로 분할되어 일련의 프레임에 걸쳐 실행되기 때문에 즉각적인 결과를 필요로 하지 않는 한 복잡한 쿼리를 실행할 때도 성능 저하가 거의 일어나지 않습니다.
AI에게 모든 포메이션 교육
이제 우리의 AI는 운전과 전투가 가능하므로 좌표가 필요한 게 분명했습니다. 이동에 엄청난 시간을 소모하고 있는 차량은 미션 게임플레이 시 공격을 위한 좌표를 요청했을 때 적절하지 않을 수 있습니다. 우리는 이 문제를 해결하기 위해 계층적으로 접근하여 드라이버 AI가 운전과 공격이라는 바쁜 업무를 처리하고 그룹 AI가 일련의 운전자를 관리하며 목적지와 대상을 알려 주도록 하였습니다.
이때 몇 가지 주요 변경 사항이 포함되었습니다. 드라이버 AI는 대상을 발견해 조준하는 대신 대상이 발견되었을 때 그룹 AI에 전달합니다. 그룹은 알려진 대상 목록을 유지하고 우선순위를 지정하여 대상을 다시 드라이버에 할당할 수 있습니다. 일반적인 상황에서 이는 드라이버 스스로가 결정하는 것처럼 플레이되지만 그룹은 주어진 시간 내에 조준할 수 있는 드라이버 수를 제한하도록 하거나 특정 대상을 다른 관심 대상 위에 덮어씌울 수 있습니다.
또한, 포메이션 주행도 가능합니다. 그룹은 특정 차량을 선두로 지정하고 다른 차량을 따라오도록 하여 이상적인 시계 방향(5시, 7시)과 거리를 두도록 합니다. 다른 드라이버는 차량의 비헤이비어 트리의 맞춤형 서비스(해당 트리 분기의 작업이 실행될 때 맞춤형 틱 속도로 실행되는 서비스)를 실행하여 이상적인 위치를 계산하고 CBS의 추적 동작을 피드 합니다.
이 기능은 게임플레이 상황에서 많은 큰 변화를 가져왔습니다. 포메이션은 몇 대의 차량을 함께 운전할 때도 좋지만 적대적인 포메이션으로 쉽게 확장할 수 있고 정의가 쉬워 그룹 내 차량 종류나 무기 배치에 따라 다양한 사전 설정을 사용할 수 있습니다. 예를 들어 그룹에 강력한 후방 갑옷과 포탑 무기가 장착된 차량과 강력한 래밍 무기가 있는 차량이 있다면 '리드 앤 팔로우' 포메이션을 사용하여 갑옷이 장착된 차량이 선두에서 매력적인 대상이 되고 래밍 차량은 플레이어의 차량을 뒤에서 공격합니다.
이 이미지에서 두 대의 AI 제어 차량(왼쪽, 아래)이 후방에서 접근하는 화면 밖 차량과 함께 플레이어의 차량(중앙)을 중심으로 포메이션을 형성하려는 것을 볼 수 있습니다.
다크 퓨처를 개발하는 과정은 독특하고 어려운 문제로 가득했지만 UE4를 사용한 덕분에 최악의 상황에서 자랑스러운 게임을 완성할 수 있었습니다.
실제 게임을 보고 싶다면 새로운 트레일러를 확인하세요. 다크 퓨처: 블러드 레드 스테이트는 5월 16일 목요일에 출시되며, 자세한 내용은 스팀(Steam) 페이지에서 확인하실 수 있습니다.