Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Unity 1week でつくったゲームにAIを実装してみる
Search
torisoup
January 13, 2021
Technology
2
3.6k
Unity 1week でつくったゲームにAIを実装してみる
Behaviour TreeでAIを実装してみた話です
Gotanda.unity #16
https://meetup.unity3d.jp/jp/events/1268
torisoup
January 13, 2021
Tweet
Share
More Decks by torisoup
See All by torisoup
もうつまらないとは言わせない!「わかりやすい」プレゼンを作るために気をつけたいこと
torisoup
8
2.4k
Unityの本を出した話
torisoup
3
730
VRMの紹介&VRM勉強会
torisoup
0
110
Unityにおける設計パターン
torisoup
17
48k
PUN2をasync/awaitで使えるライブラリつくってみた「Pun2Task」
torisoup
0
1.1k
UniTaskの使い方2020 / UniTask2020
torisoup
38
22k
UniTask入門
torisoup
6
20k
ARでVRアバターを表示するシステムを構築しよう
torisoup
2
530
Unity講習資料
torisoup
8
9.1k
Other Decks in Technology
See All in Technology
新機能VPCリソースエンドポイント機能検証から得られた考察
duelist2020jp
0
220
成果を出しながら成長する、アウトプット駆動のキャッチアップ術 / Output-driven catch-up techniques to grow while producing results
aiandrox
0
240
LINE Developersプロダクト(LIFF/LINE Login)におけるフロントエンド開発
lycorptech_jp
PRO
0
120
終了の危機にあった15年続くWebサービスを全力で存続させる - phpcon2024
yositosi
0
430
第3回Snowflake女子会_LT登壇資料(合成データ)_Taro_CCCMK
tarotaro0129
0
180
Fanstaの1年を大解剖! 一人SREはどこまでできるのか!?
syossan27
2
160
.NET 9 のパフォーマンス改善
nenonaninu
0
780
LINEスキマニにおけるフロントエンド開発
lycorptech_jp
PRO
0
330
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
2
110
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
150
OpenAIの蒸留機能(Model Distillation)を使用して運用中のLLMのコストを削減する取り組み
pharma_x_tech
4
550
サイボウズフロントエンドエキスパートチームについて / FrontendExpert Team
cybozuinsideout
PRO
5
38k
Featured
See All Featured
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.1k
Code Review Best Practice
trishagee
65
17k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Why Our Code Smells
bkeepers
PRO
335
57k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
Optimising Largest Contentful Paint
csswizardry
33
3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
17
2.3k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
6
510
Designing for Performance
lara
604
68k
4 Signs Your Business is Dying
shpigford
181
21k
Transcript
Unity 1week でつくったゲームに AIを実装してみる 2021/1/13 とりすーぷ
自己紹介 •とりすーぷ • @toRisouP • VR系の開発してる • Microsoft MVP •
(Developer Technologies) • 最近はVRChatしてます illustrations by kota(@kt_kkz)さん
あけろ!爆裂駐車場! https://unityroom.com/games/bakuretsu
Unity 1Weekでつくったゲーム •「あけろ!爆裂駐車場!」 • 次から次へと車が押し寄せる駐車場を空けるゲーム
駐車場をあけろ! •次々にやってくる車を駐車場から排除しろ! • 車はぶっ壊してもOK • 外野にふっとばしてもOK!
武器 •武器アイテムを拾って装備を変えよう!
ワンミスで終了だ! •やられたら終了! • 爆発に巻き込まれたり、フィールドから落ちたら終わり
こだわりポイント •VRM読み込みに対応 • 好きなアバターであそべる!
AIを実装してみる
このゲームにAIを実装してみよう •目標 • AIが自動的にプレイヤを操作する • 状況を判断して適切な行動を取り続ける
できたもの 公開してます:https://unityroom.com/games/akebaku_ai
手法 •「Behavior Tree」 • 階層構造をもったステートマシンみたいなもの • “状態”ではなく“行動”について評価をする
Behavior Tree Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する • 階層構造をもったグラフで AIの行動パターンを定義する • 深さ優先、左端優先
Node Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する ノード → ノード → ノード → ノード → • 各要素を「ノード」と呼ぶ
• 各ノードは状態を持つ • 成功 • 失敗 • (実行中) • (待機中)
状態 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド 中央に 移動する 待機する
ノードの種類 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する • ノードは大きく2種類に分類される • Control Flow ノード • Task ノード
Behavior Tree Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する • Task • 実際にAIがとる「行動」を表す これらがTask→
Control Flow Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する • Control Flow • 全体の”流れ”を司るノード • 種類がいくつかある • SelectorとSequence の2つがメインに使われる Control Flow
Sequence Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する • Sequence • 子のノードを左から実行 • 子がすべて成功したら「成功」 • 子が1つでも失敗したら「失敗」 になり即終了 • 要するにAND
Selector Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する • Selector • 子のノードを左から実行 • 子が成功した時点で「成功」 • 子がすべて失敗したら「失敗」 • 要するにOR
Repeat Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する • Repeat • 子の処理をずっと繰り返す
このグラフの挙動 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する
このグラフの挙動 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する 1. 敵が近くにいるか判定する 2. 見つけた敵に向かって移動する 3. 攻撃する
このグラフの挙動 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する フィールド
中央に 移動する 待機する 1. 敵が近くにいるか判定する 2. 見つけた敵に向かって移動する 3. 攻撃する ↑が失敗したら↓を実行する 1. フィールド中央に移動する 2. 待機する
Case1: 敵が近くにいた場合 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 実行中 待機中 実行中
Case1: 敵が近くにいた場合 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 「1.敵が近くにいるか?」を実行する 実行中 待機中 待機中 実行中 実行中 待機中
Case1: 敵が近くにいた場合 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 「1.敵が近くにいるか?」が成功する → 次に処理が移る 実行中 待機中 待機中 実行中 実行中
Case1: 敵が近くにいた場合 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 「2.対象に移動する」が成功する → 次に処理が移る 実行中 待機中 実行中 実行中
Case1: 敵が近くにいた場合 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 「3.攻撃する」が成功する → Sequence自体が「成功」する 待機中 実行中
Case1: 敵が近くにいた場合 Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する Selectorも「成功する」 → Repeatによって最初に戻る 待機中
Case2: 敵が近くにいなかった Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 実行中 待機中 実行中 「1.敵が近くにいるか?」を実行する 待機中 実行中 待機中
Case2: 敵が近くにいなかった Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 実行中 待機中 実行中 「1.敵が近くにいるか?」を実行する → 失敗する 待機中 待機中
Case2: 敵が近くにいなかった Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 待機中 実行中 「1.敵が近くにいるか?」を実行する → 失敗する → 続きは実行されずSequence自体が 失敗となる 待機中 待機中
Case2: 敵が近くにいなかった Selector Sequence 敵が近くに いるか? Sequence 対象に 移動する 攻撃する
フィールド 中央に 移動する 待機する 実行中 実行中 Selectorにより次のブロックに処理が移る 待機中 待機中 実行中
アセットを使うと楽 •Behavior Designer
昔に解説してるので参考になれば •【Unity】 Behavior TreeでAIを作る • https://www.slideshare.net/torisoup/unity-behavior-treeai
UnityでAIをつくっていく
AIを実装していく •今回は「Behavior Designer」を使って、 「あけろ!爆裂駐車場!」にAIを実装する
方針 「Playerのコンポーネントには手を加えない」 • プレイヤーの移動、攻撃、アイテム装備…、 すべて同じコンポーネントをそのまま使いまわす
差し替える部分はどこか? •「入力イベント」のみを差し替える
人間が遊ぶ場合 人間 入力イベント プレイヤキャラクタ
AIの場合 AI 入力イベント プレイヤキャラクタ
イベントを使い回せば ここの処理は全く同じにできる! 入力イベントの発行者が 異なるだけで
入力の抽象化レイヤを挟む 人間やAIから入力されたイベント をいい感じに変換するレイヤ
抽象化 •入力イベント発行機構を抽象化しておく
人間が操作するとき •キーボードからの入力をイベントに変換する
AIが操作するとき •AIからの入力をイベントに変換する • AIに「ゲームパッド」を持たせるイメージ
プレイヤ初期化時に差し替える •差し替えるのは基本これだけ • これでAIがプレイヤを操作する口ができた
これで入力イベントが共通化できた IInputEventProvider
他の下準備 •AI用にいくつか下準備をしておく
Playerにコンポーネントを追加 •「Behavior Designer」と「NavMeshAgent」
AI用の情報提供クラス •AIがゲームの状態を知るための仲介クラス
AIの実装
ロジック 1. 燃えている車があったら、逃げる 2. アイテムが近くにあったら、拾う 3. 車があったら、近づいて攻撃する 4. ステージ中央に向かう
ロジック 1. 燃えている車があったら、逃げる 2. アイテムが近くにあったら、拾う 3. 車があったら、近づいて攻撃する 4. ステージ中央に向かう 優先度が高い処理から試行していく
条件を満たさない場合は次の処理を試す
AIの実装手順 1. Taskノードを自作する 2. ノードグラフを構築する 3. 動作確認して調整する
Taskノードの自作 •Behavior Designerは“行動”を自作可能 • C#のスクリプトを書けば簡単に作れる • 必要なタスクを自分で作ってしまえばOK
車を探すTask
車を探すTask 毎フレーム実行される Runningを返すと継続 Success / Failureを返すと終了
例:「移動する」Taskの実装 InputEventProviderに渡してPlayerの移動に反映する NavMeshAgentから得た経路の情報を
結果
None
4つのブロックにわかれている
1.燃えている車が近くにあったら逃げる 燃えている車が 近くにあるか? 逃げる先を決定 移動する ちょっと待機
2.アイテムが近くにあったら拾う アイテムが 近くにあるか? 移動する
3.車があったら攻撃しにいく 車を探す 移動する 攻撃する
4.ステージ中央に向かう
動作させながら微調整 •パラメータを調整する •挙動を細かく調整する
例:調整箇所 •「攻撃するために移動する」 • 武器ごとにリーチに差がある • ロケランは自爆の可能性がある → 装備武器ごとに対象にどれだけ近づくか変える
調整 •武器ごとにどれだけ車に近づくか変える • 近接武器はより近づく、ロケランは遠くで止まる
他にも調整したい箇所は山程ある •移動中に障害物でスタックしたときどうする •攻撃が届かないシチュエーションを減らす •場外に飛んでいった車に反応しないようにする •戦車から逃げる •爆風に自分から突っ込まないようにする
まとめ •Behavior Treeはいいぞ • 比較的かんたんにAIを実装できる! • それっぽく動くところまでの実装時間は約3時間 • ただしそこから微調整で+6時間くらい… •
あらかじめAIの実装を許容する設計にしておく必要はあり • 適切に処理を抽象化しておこう
以下おまけ
AIを移動させる •Unityには「NavMesh」という機能がある • 経路探索を用いてオブジェクトを移動させる機能 • これを使えば障害物を避けていい感じに移動してくれる
NavMeshAgentの利用方法 •NavMeshAgent • NavMeshに沿ってオブジェクトを動かすコンポーネント • デフォルトだとこのコンポーネントで勝手に移動していく → NavMeshAgentによる自動移動を今回はOFFにする
NavMeshを使ったAI操作
NavMeshを使ったAI操作 NavMeshAgentの認識する「現在地」を 自分のtransform位置に補正する
NavMeshを使ったAI操作 NavMeshAgent.desiredVelocity で 経路探索の結果から移動するべき方向が取得できる
NavMeshを使ったAI操作 移動するべき方向をInputEventProviderに渡して Playerの移動入力とする