2019の記事として書かれています。Network略してHTN)というアルゴリズムについて勉強したことをまとめてみます。学び始めたばかりなので、間違えてそうなとこ、もっと良くなる点などあればアドバイスいただければ幸いです。実際に自分でHTNを実装してみた感想の3つを書ければと思っています。〇ゲームAIの種類ゲーム内におけるキャラクターAIの仕組みを簡潔に言えば、環境から何らかの情報を受け取り、何らかの情報を出力すると言えます。ここで重要なのは、受け取った環境の情報からアウトプットする上で、どのような意思決定を行うのかという点です。周りのマップ環境やキャラクターの置かれている状況などの情報をもとに、次に自分がどんな行動をするべきなのかみたいなことを決定するアルゴリズムが必要になります。その意思決定の手法は、以下のような種類に分けられることが多いです。ルールベースステートベースビヘイビアベースタスクベースゴールベースユーティリティベースシミュレーションベースなどなどそれぞれの手法がどのようなものなのかは他の人がたくさん説明してくれているので省略します。こちらの記事が簡潔にまとまっていました。詳しく知りたい方は、スクエニの三宅陽一郎さんの書かれている本や講演記事などを見るとめちゃめちゃ勉強になります。僕もとてもお世話になっております。三宅さんが作成するスライドはいつも情報量が半端ないです。ゲームAI入門(前半)〇最近の流行り上記の手法の中での最近の主流は、ビヘイビアベースです。Treeという、木構造状に定義した振る舞い(ビヘイビア)を環境に合わせて実行していくビヘイビアベースの手法を使うのが一般的ではないかと思います。その理由としては、僕は以下が挙げられると思ってます。Networkという名前にもある通り、HTNはタスクベースのアルゴリズムになります。タスクベースやゴールベースなどの手法が他の手法と違う点は、プランニング(計画)を行うという点です。プランニングとは、なにかしらの目的達成のために実行する必要のある行動計画を自動で組み立てるアルゴリズムのことです。ビヘイビアベースなどは、現在の環境情報に応じて反射的に行動を決定してしまうアルゴリズムです。そのため、その前の行動を参考にしたり、その行動を行った影響などを考慮した上で意思決定することは難しいです。ゲームが複雑化、巨大化していく中でより人間らしく、より頭が良いと思われるAIを作成していくには、プランニングの要素も必要となってきます。反射的に行動している人よりも、何か目的に沿って一連の行動をしているように見える人の方が頭良さそうですよね。TreeとHTNを組み合わせたハイブリッド型のAIというのも増えてきているようです。いうことは、ここらでHTNのようなタスク指向のAIの仕組みを学んでいくというのは結構アリなのでは?と思って、勉強し始めた次第です。前置きが長くなりましたが、ここからHTNについての話を進めていきます。Proに紹介されている内容が元となってます。これを読むことから始めましょう。◯HTNの概要HTNは階層化型タスクネットワークと日本語で表せますので、「タスク」、「ネットワーク」、「階層化型」という順番でHTNとは何かを見ていきましょう。上記でも述べたように、HTNはタスクベースのアルゴリズムです。タスクベースで使用するタスクという単位は、僕の理解では若干曖昧なんですが、一般的に使用してる意味と変わらないのではと思ってます。ToDoリストとか作成したことあると思うんですが、あれって抽象的なタスク、具体的なタスク、時間軸的に長期間のタスクなどいろいろ粒感がバラバラに混ざってしまうことって多くないですかね?僕だけ?タスクベースもそれと同じで、大小いろいろなタスクがあります。次に、ネットワークについて。タスクベースAIではただタスクを羅列するだけではなくて、タスク同士に関係性を持たせます。タスクAを実行するには先にタスクBをやる必要がある、とか、タスクCの実行にはタスクD/E/Fのどれかを実行しないといけないみたいな感じです。やって考えていくと、それぞれのタスク同士で関係性の線が繋がっていくのがイメージできるでしょうか。2つでタスクネットワークは構築できるのですが、それぞれのタスク間に階層構造を持たせることでより抽象度高く、より効率的にプランニングを行うことができます。タスクネットワークに階層構造を持たせることで、抽象度の高いタスクから具体的なタスクへのタスクの分割が行いやすくなります。人が行動を計画するときの思考と似ているので、タスクネットワークを構築しやすいことが多いのもメリットです。〇HTNの構成要素この画像が、HTNを表す全体像になります。それぞれ、どんなものなのかを見ていきましょう。StateそのAIから見た世界そのもの。AIのインプットとなる環境情報をまとめたもの。世界すべてを記す必要はなく、AIにとって必要となる情報だけを更新し続ければよい。俗に言う、Blackboardみたいなもの。・Domain階層化されたTaskの全体を表した知識群。ここに問い合わせれば、Taskのことがなんでも分かる場所(という認識)・TaskHTNの基本的な単位。Taskの2種類に分けられる。階層的に上位のタスク。複数のMethodを持ち、それらを管理することで様々なタスクの分岐を生む。Stateの状況に合ったものを探し、そのMethodのSubTaskを後続に流す。Taskに保有される。Methodは以下の2つを持つ。TaskAIが行動を起こす上での最小単位。これ以上小さいタスクはない。Taskは以下の3つを持つ。・Plannerプランニングを行い、プランを管理する本体。Domainを用いて最適なTaskリスト(Plan)を作成し、現在行うべきTaskを監視する。Plannerは以下の3つの状態のどれかが起きると、再プランニングを行う。RunnerPlannerから受けとったタスクリストの実行と管理を行う。途中でタスクの実行に失敗するか、全てのタスクをやり切るまで監視する。結局、何ぞ?・タスクを2種類に分けることで、タスク同士に階層構造を持たせたタスクベースAI・タスク同士の関係性をもとにした上で、あるタスクを実行するまでのプラン作成を行う今回の成果物GitHubりぽじとり今回書いたコードは上記になります。最初に断っておきますが、未完成です。泣キャラクターの行動を実際に実行するところ(Operator周りの実装)まで間に合わず、せっかくUnityで作成していたのにUnityの恩恵を全く受けられていない状態です。この記事を書くために再度いろんな記事を読み直して思ったのですが、Domainの実装をミスった感があります。このままじゃまだまだゲームの使い物にはなりませんが、HTNを実装する上で何かの助けになれば嬉しいです。今後も実装は続けようと思っているので、長い目で見てやってください。解説コードに関してはざっくり解説していきます。}Plannerクラスの役割は与えられたルートタスク(一番上位のタスク)を元に、タスクリストを作成することです。ここで説明が必要そうなのはTaskListToProcessですかね。これは、実行可能かを検証する予定のタスクリストみたいなもので、一番最初はルートタスクのみが入ります。こちらの画像が分かりやすいと思います。Planに格納されているかのどちらかになります。Taskの状態まで遡り、違う分解方法を試します。List<Method>();}タスク周りの実装は上記のように行いました。基本的に構成要素で説明した通りの内容です。これらを継承して、実際のタスクの中身を作ることになります。以下のように移動タスクを作ってみました。Taskが保有するMethodはこんな感じ。現在のCurrentTaskを実行し、次のTaskがあれば更新する。その上で、現在のPlanの状態を返す。}PlanRunnerでは、上記のように今行うべきタスクをプランから取得して実行していってます。今後への課題いろいろ考えて実装してみたはいいのですが、当方よわよわエンジニアのため、いろいろ漏れてるところがあります。Domainのあり方HTNについて、僕が一番うまく理解できていなかった部分です。タスク同士の関係性などの全ての知識をここに集めることが必要でしたが、僕はリポジトリ的な立ち位置で使用していました。最終的なプランはドメイン層が返してあげられるぐらいまで作りこんでいいのだと思います。Plannerはその補助を行う役割かと。Operatorの実装Operatorはキャラクターの実際の行動部分に当たるのですが、タスクにうまく引数を渡す機構を作らないといけなかったり、行動の状態の監視を行う必要があったりなどいろいろと今の僕には難しいなと思うことが多かったです。文字を出すだけでなく、キャラを動かすまでやって、ゲームAIを作ったって言いたいですね。Treeのようなグラフィカルな操作ができたりしてほしいと感じます、また、コードの自動生成も行えないと同じようなタスクをちまちま作ることになって大変です。終わりにHTNに関しては日本語の資料は比較的少ないこともあり、1から実装するのは難しいと感じました。この記事を読んでゲームAIおもしろそうやなと思っていただけたら、記事を書いていただけると嬉しいです。Seimiya@tyemiyaFollow株式会社ディー・エヌ・エー1999年に創業した株式会社ディー・エヌ・エーはゲームを中心に、オートモーティブ、ヘルスケア、スポーツなどの事業分野にも進出し、インターネットや人工知能(AI)を活用した新しい挑戦を続けています。upLoginユーザーは見つかりませんでした。