GAME AI - LOD
2024.02.25 - [Game AI] - AI 스케줄링
개요
게임 그래픽에 LOD를 적용하듯, AI에도 LOD를 적용할 수 있다. 가령 어떤 캐릭터는 복잡하고 정교한 행동을 하고 어떤 캐릭터는 단순한 행동을 하도록 할 수 있다.
그러나 게임 AI의 LOD는 그래픽처럼 단순히 거리만으로 처리할 수 없다. 그래픽과 달리 AI 캐릭터들이 우리가 보고 있지 않을 때도 항상 행동하길 기대하기 때문이다.
AI의 LOD는 그 캐릭터가 게임에서 어떤 역할을 하냐에 따라 정해지기도 한다.
LOD 스케줄링
게임 AI의 LOD를 처리하는 간단하고 효율적인 방법은 스케줄링 시스템과 같이 활용하는 것이다. LOD에 따라 다음 요소에 차별을 둘 수 있다.
- 빈도 : LOD가 낮으면 업데이트 간격이 길다. 다만 업데이트 간격이 너무 길어진다면 overshooting이 일어날 수 있다. (ex. 캐릭터가 지정된 경로를 벗어나버림)
- 우선순위 : LOD가 낮으면 낮은 우선순위를 줘서 작업에 처리되는 시간을 조금만 준다. 캐릭터가 멍청하게 행동할 수 있다.
위 두 가지를 동시에 쓸 수도 있다. 그래도 어쨋든 언급된 단점들을 피하지는 못한다. 이런 경우에 AI의 행동 자체를 바꾸는 편이 더 나을 수 있다.
행동(Behavioral) LOD
현재 AI의 LOD에 따라서 다른 행동을 취한다.
예를 들어, 거리를 걷는 AI 캐릭터가 있다고 하자. 플레이어의 관심 영역에 있는 AI들은 충돌을 피해서 이동하지만, 그렇지 않은 AI들은 그냥 충돌 자체를 꺼버려서 서로 자유롭게 통과할 수 있게 한다.
LOD로 인해 행동이 전환 될 때 관련된 데이터도 로드/릴리즈가 필요하다. 이를 위해서 행동 자체에 Entry/Exit 프로세스를 구현할 수 있다. 그러나 행동 전환간 동일한 데이터를 처리한다면 이런 과정이 필요없으므로 행동을 전환할 때 데이터를 유지할지 로드/릴리즈할지를 판단하기 위해서 transition을 구현해야 할 수도 있다.
Hysteresis
hysteresis는 한국어로 이력이라고 번역하는데.. 대충 설명하자면 A->B로 갈때와 B->A로 갈때의 경로가 다른 그런 폐곡선이라 할 수 있다.
이런 개념이 왜 필요하냐? 어떤 캐릭터의 LOD 조건이 플레이어와의 거리라고 하자. 그리고 그 거리를 10미터라고 가정하자. 플레이어와 10미터의 간격을 두고 비슷한 방향,속도로 이동하는 AI 캐릭터는 행동이 짧은 시간동안 계속 변하게 된다. 그리고 이건 자원 낭비일 뿐더러 캐릭터가 이상하게 보일 수 있다. 이를 해결하기 위해 위에서 hysteresis라는 개념을 쓴다. LOD가 바뀌는 경계가 그때 그때 달라지는 것이다.
이를 위해 각각의 행동들은 LOD의 경계를 범위(최소, 최대)로 갖는다. 만약 경계에서 벗어나면 다른 행동을 선택한다. 여기서 다른 행동을 선택하는 방식은 여러 가지가 있다.
- 가능한 행동 중 선택 :가장 효율적인 방법이라 할 수 있는데, 이분탐색을 통해 현재 범위에 맞는 행동을 선택한다. 이 경우, 행동들이 소팅되어 있어야 하는데, 보통 소팅의 기준은 범위의 중간값으로 한다.
- 리스트의 첫번째를 선택 : 이것도 효율적인 방법 중 하나. 이경우도 마찬가지로 행동들이 우선순위등에 따라 정렬되어있어야 한다.
- 기준점이 중앙값에 가까운 행동을 선택 : 기준점이 중앙값에 가깝다면 해당 행동은 다른 행동보다 오래 실행될 가능성이 높다. entry/exit 프로세스가 오래걸릴 때 유용하다.
- 가장 범위가 적은 행동을 선택 : 범위가 적다면 특정 상황에 특화된 행동이라는 가정이 깔려있다.
LOD 조건에 따라 실행 가능한 행동이 하나도 없는 경우는 있어서는 안 된다. 따라서 모든 조건을 커버하는 행동이 있어야 하는데 이를 Fallback Behavior라 부른다.
Group LOD
만약 AI캐릭터가 많다면 개별 캐릭터들을 하나 하나 연산하기 보다는 그룹으로 묶어 연산하는 것이 효율적일 것이다. 이때 Group은 Hierachical하게 구성할 수 있다.
이 경우에도 개별 캐릭터들은 자신만의 데이터를 들고 있는데, 캐릭터가 엄청 많다면 메모리를 많이 잡아먹을 것이다. 따라서 LOD가 높은 상황(정밀도가 떨어지는 상황)에서는 개별 캐릭터의 데이터를 그룹 전체의 데이터로 압축할 수 있다. 이 때 개별 캐릭터들의 데이터를 분포화 한다. 이후 중요도가 다시 높아진다면 (LOD가 낮아진다면) 분포에 맞게 캐릭터들에게 값들을 지정해준다. 개별 캐릭터들 관점에서는 속성들이 바뀌었지만 그룹 전체로 본다면 분포는 비슷하게 된다.