【Unreal Engine】強化学習を行う方法を調べてみた

# 目次
[1. Unreal Engine上で強化学習を行いたい理由](#1-Unreal-Engine上で強化学習を行いたい理由)
[2. 各種手法の比較](#2-各種手法の比較)
>[2-1. 内部実行系の手法](#2-1-内部実行系の手法)
以下の４つの方法について紹介します。
・Python Editor Script Plugin
・UneralEnginePython
・Python Foundation Packages
・Neural Network Inference
>[2-2. 外部通信系の手法](#2-2-外部通信系の手法)
以下の４つの方法について紹介します。
・Mind maker
・UE4ML
・ML Adapter
・Learning Agent

[3. 結局何を使えばいいのか](#3-結局何を使えばいいのか)



※記事中のUEはUnreal Engineの略です。


# 1. Unreal Engine上で強化学習を行いたい理由
　強化学習は、機械学習の一分野であり、エージェントが環境と相互作用しながら、試行錯誤を通じて最適な行動を学習する手法です。ゲームエンジンと強化学習は相性が良く，例えばUnityではすでにその手法が確立されていますが，Unreal Engine上での強化学習についてはいまだに情報が少ないのが現状です。

　Unreal Engine上で強化学習を行う利点については以下のようなものが考えられます。

 - リアルな環境のシミュレーション
　Unreal Engineは、強力なグラフィックス機能や物理エンジンを備えており、リアルな環境のシミュレーションを行うことができます。そのために強化学習エージェントが現実世界の振る舞いを学ぶための理想的なプラットフォームとなりえます。例えば、自動運転車の制御やロボットの動作制御など、実際の物理環境での学習を必要とするタスクにおいて、Unreal Engineは非常に有用だと思われます。

 - 統合された開発環境:
　Unreal Engineは、ゲーム開発において強力な開発環境を提供しています。強化学習の研究や開発においては、実験環境のセットアップやデータの収集などが課題となりますが，Unreal Engineを使用することで、シミュレーションの設定や結果の視覚化、デバッグなどを容易に行うことができるようになると思われます。




# 2. 各種手法の比較
　まず大まかにまとめるとUnreal Engine上で強化学習を行うには以下の２つの方法があります。
 - UE内で学習を実行する
 - 外部のプログラムと通信して学習を行う

　UE内で学習を実行する場合，Unreal Engineのビルトインのスクリプト言語であるBlueprintやC++，もしくはPythonを使用して強化学習アルゴリズムを実装し，学習プロセスを制御する事になります。この方法では，エージェントの学習とゲームの実行が同時に行われるため，リアルタイムで学習の進捗を観察することができます。

　一方で，外部のプログラムを利用する場合はUnreal Engineと外部の強化学習フレームワークやライブラリを組み合わせます。Unreal Engine内で環境のシミュレーションを行いながら，学習のためのデータや状態を外部プログラムに送信し，外部の強化学習アルゴリズムによって学習を実行します。この方法では，より高度な強化学習アルゴリズムやリソースを利用することができますが，Unreal Engineと外部プログラムの間でデータの送受信や同期を行う必要があります。

以下では今回調査した方法を，上記の２手法に分類し紹介します。

## 2-1. 内部実行系の手法



### Python Editor Script Plugin
https://docs.unrealengine.com/5.2/en-US/scripting-the-unreal-editor-using-python/

　Python Editor Script PluginはUE5から標準で搭載されているプラグインです。このプラグインを導入することでPythonをゲーム内ターミナル，テキストファイル，BluePrintから実行することができるようになり，またライブラリも導入することができます。
　一方でこのプラグインの致命的な欠点として，エディター上でしか使用できず，ランタイム中（ゲーム実行中）は動作させられなかったので強化学習用途では使うことができません。

参考：
[Python Setup For Unreal Engine 5 Tutorial](https://dev.epicgames.com/community/learning/tutorials/Bb7R/python-setup-for-unreal-engine-5-tutorial)：Pythonの実行(テキスト，ファイル)
[Run Python In Blueprints Utilities](https://dev.epicgames.com/community/learning/tutorials/yrZl/run-python-in-blueprints-utilities-build-editor-tools-unreal-engine-5-tutorial)：BluePrintからの実行
[Python Install Modules With PIP](https://www.youtube.com/watch?v=Qt0AW08REKg)：ライブラリの導入



### UneralEnginePython
https://github.com/20tab/UnrealEnginePython

　UnrealEnginePythonは有志が開発したUE4用のプラグインです。このプラグインを導入することでPythonをゲーム内ターミナル，テキストファイル，BluePrintから実行することができるようになり，またライブラリも導入することができます。また，こちらのプラグインではランタイム中もPythonを実行することができます。
　一方で現在は開発が停止しており，UE5では動かせないというのが難点です。

<details><summary>細かい実装</summary><div>

---

[このスレッド](https://github.com/20tab/UnrealEnginePython/issues/867)などによるとUE4.27でも動かせるようですが，自分は上手くいかなかったので今回は例としてUE4.23での実装を紹介します。

まずはEpic Games Launcherを起動して，`ライブラリ`へ移動します。
`Engineバージョン`の横の+マークを押すと以下の画像のようになるので，プルダウンメニューから`4.23.1`を選択し，インストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/80717b07-432f-5822-e640-4e475864d769.png)
また，このバージョンのUEはVisualStudio2017にしか対応していないので，PCに入っていない人はインストールしてください。

UE4.23.1のインストールが終わったら起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/aa10d78d-de38-9bed-ee10-81d05f3cf8c4.png)
このような画面が出てくるので，`新規プロジェクト`>`C++`と選択し，適当にプロジェクトを作成します。

[こちら](https://github.com/20tab/UnrealEnginePython/releases)から`UnrealEnginePython_20190508_4_22_python36_embedded_win64.zip`をダウンロードしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/7438d6da-c7a1-a6de-8ca3-fead21bb58fa.png)

解凍したフォルダ(`UnrealEnginePython`)を先ほど作成したプロジェクトのフォルダの`Plugins`下に配置します。
パスは恐らくこのようになります。
`\Unreal Projects\[プロジェクト名]\Plugins\UnrealEnginePython`

次に[こちら](https://github.com/20tab/UnrealEnginePython)からソースコードをダウンロードしてきてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/417d0031-9159-daf7-7fc2-385343ae5fd2.png)

ダウンロードした圧縮ファイルを解凍し，中の`\UnrealEnginePython-master\Source\UnrealEnginePython\UnrealEnginePython.Build.cs`を適当なテキストエディタで開きます。
11行目の
```cs
private string pythonHome = "";
```
に適当な`python.exe`までのパスを入れてください(パスにpython.exeは含めません)。

保存したら，今編集したファイルを含む`Source`フォルダをコピーし，
`\Unreal Projects\[プロジェクト名]\Plugins\UnrealEnginePython\`下に貼り付けます。

そのままプロジェクトフォルダ下にある`[プロジェクト名].uproject`を右クリックし，`Generate Visual Studio project files`を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/ffa2eff1-78fe-4452-f7f5-58bd036c3fe6.png)

次に`[プロジェクト名].sln`をVisual Studio2017で開き，`ローカルWindowsデバッガー`をクリックします。そのままビルドが上手くいけば，プロジェクトにUnrealEnginePythonプラグインが導入できているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/586b1958-03fb-76ad-842a-5c9487c3262b.png)

プラグインの使い方や，Pythonライブラリの導入は下の記事を参考にしてください。

---

</div></details>

参考：
[UE4でPythonを使ってみる](https://qiita.com/simonritchie/items/58fe6d4d3c411c8c062f)





### Python Foundation Packages
https://www.unrealdirective.com/tip/python-foundation-packages-plugin

　Python Foundation PackagensはUE5の実験段階のプラグインです。NumpyやPytorchが公式サポートされるとのことですが，現状非常にドキュメントが少ないため詳細は不明です。





### Neural Network Inference
https://docs.unrealengine.com/5.0/en-US/API/Plugins/NeuralNetworkInference/

　今回の記事の趣旨からは外れますが，単にUnreal Engine上で学習済みモデルを動かすだけならNeural Network Inference(NNI)プラグインを使うのが良さそうです。Pytorchなどで学習を行ったモデルをONNX形式で出力すれば，このプラグインを用いてUE5上で実行することができます。似たような有志のプラグインに[SimplePytorch](https://github.com/AntiAnti/SimplePyTorch)というものもありますが，こちらはUE4用なのでUE5では動きません。

参考：
[OnnxRuntime-UnrealEngine](https://github.com/microsoft/OnnxRuntime-UnrealEngine)：Microsoftが出しているNNIのサンプルコード。
[Neural Network Inferenceプラグインについて](https://historia.co.jp/archives/26238/)




## 2-2. 外部通信系の手法
### Mind maker
https://github.com/krumiaa/MindMaker

　Mind makerは有志が開発した強化学習用のプラグインであり，UE4とUE5の両方で動作します。強化学習アルゴリズムとしてA2C，DQN，PPO，SAC，TD3，DDPGの６つが用意されており，その中から好きなものを選び学習を行うことができます。また，有料ながらも[倒立振り子のサンプルプログラム](https://unrealengine.com/marketplace/en-US/product/neurostudio-self-learning-ai)が用意されているので，取り敢えず何かを動かしてみたいという人にはおすすめです。仕組みとしてはUE上で取得したObservationsとRewardの値を外部の実行ファイル(.EXE)へ送信し，そこからActionを受け取るという様になっています。
　あえて難点を挙げるとすれば、プラグインの完成度が高いため、独自の強化学習アルゴリズムを使用したい場合などの拡張性はあまりありません。

<details><summary>細かい実装</summary><div>

---

[プラグイン](https://www.unrealengine.com/marketplace/en-US/product/mindmaker-ai-plugin)と[サンプルプログラム](https://www.unrealengine.com/marketplace/en-US/product/neurostudio-self-learning-ai?sessionInvalidated=true)を導入してください。

Epic Games Launcherの`ライブラリ`>`マイダウンロード`から実行したいバージョンのUEにプラグインをインストールし，そのバージョンでサンプルプロジェクトを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/1e3ed5ea-96dd-25ae-8cab-b8fce1dd32f3.png)

サンプルプロジェクトを開くと，倒立振り子のようなものが実行できるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/c2ef47ea-03d1-e035-0a00-9714d4424d83.png)
↑サンプルプロジェクトを実行してる様子

強化学習関連のBruePrintは`cart_BP`にあるので参考にしてください。

---

</div></details>

参考：
[Creating a Custom Deep Reinforcement Learning Environment](https://towardsdatascience.com/create-a-custom-deep-reinforcement-learning-environment-in-ue4-cf7055aebb3e)：公式ドキュメント






### UE4ML
https://docs.unrealengine.com/5.2/en-US/API/Plugins/UE4ML/

　UE4MLはその名前の通りUE4上で機械学習を行えるようにするプラグインです。自作のUE4のゲームをOpenAI Gymと同じように扱えるようにするプラグインと，Pythonモジュールのセットになっており，外部のPythonからユーザー入力を行ったり、ゲーム内の情報を外部Pythonが取得出来るようになっています。
　ただUnrealEnginePython等と同様にUE5では使えないのが難点です。

<details><summary>細かい実装</summary><div>

---

マーケットプレイスからEpic Gamesが出しているAction RPGサンプルを入手し，UE4.27でプロジェクトを作成します。

https://www.unrealengine.com/marketplace/ja/product/action-rpg-01

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/e7c44d64-35f1-9a95-12e7-204601a3b030.png)


プロジェクトを開き，`編集`>`プラグイン`から`UE4 support for ML`のプラグインを有効化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/230290fa-1cf0-b45d-a221-9f3c7c891dc1.png)

再起動を促されるので再起動します。

`ファイル`>`プロジェクトをパッケージ化`>`Windows(64-bit)`からサンプルプロジェクトをパッケージ化します。このときファイルの出力先のパスにスペースが含まれないようにしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/161b40f0-8994-73ab-3b9b-0597110bea75.png)

次にPythonにUE4MLのモジュールをインストールします。
コマンドプロンプトを開いて以下のコマンドを実行します。
```
cd C:\"Program Files"\Epic Games\UE_4.27\Engine\Plugins\AI\UE4ML\Source\python
pip install -e .
```
`C:\Program Files\Epic Games\UE_4.27\Engine\Plugins\AI\UE4ML\Source\python\examples\custom_params.py`を修正します。
```py
# 6行目にset_executableを追加
from ue4ml.runner import UE4Params, set_debug, set_executable # 
import argparse

# 49行目(envインスタンスを作る前)に以下の行を追加
set_executable(r'D:\Documents\UEpackage\WindowsNoEditor\ActionRPG.exe')
env = env_cls(ue4params=params, server_port=args.port)
```
set_executableで設定する値は先ほどパッケージ化したサンプルプロジェクトの実行ファイル(.exe)までのパスです。`r`を忘れるとエラーが出ます。

`C:\Program Files\Epic Games\UE_4.27\Engine\Plugins\AI\UE4ML\Source\python\ue4ml\core.py`を修正します。
```
# 15行目に追加
import numpy as np

# 153行目を変更
return gym.spaces.unflatten(self.observation_space, np.array(raw_obs))
```

コマンドプロンプトを開いて以下のコマンドを実行します。
```
cd C:\"Program Files"\Epic Games\UE_4.27\Engine\Plugins\AI\UE4ML\Source\python\examples
python custom_params.py
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/38194fa7-e1c6-06d7-9c53-e922dbff82a8.png)

キャラクターがそれらしく動いているのを確認できました。

---

</div></details>

参考：[UE4.26 に新規追加されたUE4MLを試す](https://tech.morikatron.ai/entry/2020/12/14/100000)





### ML Adapter
https://docs.unrealengine.com/5.1/en-US/API/Plugins/MLAdapter/

　ML Adapterは前述のUE4MLに似た仕組みを持つ，UE5向けの実験段階プラグインです。[こちらのスレッド](https://forums.unrealengine.com/t/ue5-unreal-engine-support-for-machine-learning/514171/2)にはいくつか実装例もあるので問題なく利用できると思われます。
　しかし，同スレッドに
>it is increasingly likely ML Adapter will be sunset later this year in favor of a new plugin we are intending to release.（MLアダプターは今年後半には廃止され、新しいプラグインがリリースされる予定です。）

とあるため，将来性は乏しいかもしれません。

参考：
[MLAdapter github](https://github.com/EpicGames/UnrealEngine/tree/release/Engine/Plugins/AI/MLAdapter)：Github
[Python example](https://github.com/EpicGames/UnrealEngine/tree/release/Engine/Plugins/AI/MLAdapter/Source/python/examples)：サンプルコード





### Learning Agent
https://dev.epicgames.com/community/learning/tutorials/8OWY/unreal-engine-learning-agents-introduction

　Learning AgentはUE5向けの未リリースプラグインであり，ML Adapterの後継プラグインという扱いのようです。将来的には外部のPythonで実行されているPytorchと連携可能なC++(Brueprint)ライブラリが実装されるそうです。
　ただ，現状(UE5.2)では完全には機能が実装されていない上に，ドキュメントが少ないので正式リリースを待った方が良さそうです。

<details><summary>細かい実装</summary><div>

---

現在のバージョン（UE5.2）で利用するにはソースからUnreal Engienをビルドする必要があります。
 - [こちらの記事](https://www.unrealengine.com/ja/ue-on-github)に従いUnreal EngienのGitHubリポジトリにアクセスできるようにしてください。
 - Epic GamesのGitHubから[ue5-main](https://github.com/EpicGames/UnrealEngine/tree/ue5-main)ブランチをダウンロードします(かなり時間がかかります)。
 - ダウンロードしたフォルダ内にある`UnrealEngine/Setup.bat`を実行します(かなり時間がかかります)。
 - `UnrealEngine/GenerateProjectFiles.bat`を実行します。
 - 生成された`UnrealEngine/UE5.sln`をVisual Studio 2022で開いて`ビルド`>`ソリューションのビルド`を実行します(かなり時間がかかります)。

自分の場合ここでエラーが出てしまいましたが，うまくいけば`編集`>`プラグイン`から`Learning Agent`のプラグインを有効化できるようになっているはずです。Learning Agentのクラスの使い方については，下の参考の記事を見てみてください。

---

</div></details>

　
参考：
[Learning Agents Introduction](https://forums.unrealengine.com/t/tutorial-learning-agents-introduction/835859/27)：Learning Agentに関するスレッド
[Early Explorations of Learning Agents in Unreal Engine](https://medium.com/@gensen/early-explorations-of-learning-agents-in-unreal-engine-ef74b058161e)：導入と簡単な紹介についての記事
[Killers and Explorers: Training RL Agents in Unreal Engine](https://medium.com/@gensen/killers-and-explorers-training-rl-agents-in-unreal-engine-7976a83b01d7)：実装例の記事






# 3. 結局何を使えばいいのか
　Unreal Engineで強化学習を行う方法はいくつもあり，一体どれを利用すれば良いのか分かりずらい状況となっています。そこで，今回調べたことを簡単にまとめると以下のようになります。
 - 学習済みモデルを動かしたい人→NNI
 - 手っ取り早く強化学習を行いたい人→Mind maker
 - UE5でなくても良い人→UneralEnginePython, UE4ML
 - 今すぐ強化学習を行いたいわけではない人→Learning Agent

　また今回紹介した物以外にも，[MachineLearningRemote-Unreal](https://github.com/getnamo/MachineLearningRemote-Unreal)や，[TensorFlow-Unreal](https://github.com/getnamo/TensorFlow-Unreal)など，有志が開発したプラグインがいくつかあるので試してみても良いかもしれません。

(この記事は研究室インターンで取り組みました：https://kojima-r.github.io/kojima/)