即興魔法を使おう　~自然言語処理技術で自分の考えた詠唱に合った効果の魔法を使うシステム~

# はじめに
皆さん魔法は好きですか？
自分は好きです。
どれくらい好きかというと、昔脳波を測定して頭の中で考えるだけで魔法を使えるようにする
研究をしていたぐらい好きです。（余談ですがその研究は最終的に音の長さが違う魔法なら判別して使えるようになりました）

何がいいかというと色々ありますが、その中でも魔法の詠唱が好きという方は多いと思います。
色んな小説や映画で、色んな魔法使いが詠唱して魔法を使う姿を見て、こんな魔法を使いたいな、と思った方は多いんじゃないでしょうか。
今回はそんな願望を形にしました。
自然言語処理技術を使って、自分がその場で考えた詠唱によってその詠唱に合った魔法を唱えることが可能なシステムを作成しました。（所要時間３日）

今回のシステムのコードを置いた場所は以下。
とりあえず試してみたい人はまず使い方の項目を参照してください。

https://github.com/gyokuro33/ChantMagick

# 何を作ったか
こんなのです。
自分の詠唱した言葉によって、色んな効果の魔法が発動します。
音声をオンにしてみてみてください。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">燃えろ <a href="https://t.co/aGdeVIG4QL">pic.twitter.com/aGdeVIG4QL</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340624219101487104?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ファイヤーシュート <a href="https://t.co/iXA46RhDnK">pic.twitter.com/iXA46RhDnK</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340628430019182595?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">広がって燃えろ <a href="https://t.co/it9NvAUnoe">pic.twitter.com/it9NvAUnoe</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340629449629306886?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">雷よ飛べ <a href="https://t.co/2E28PGpGKI">pic.twitter.com/2E28PGpGKI</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340630016858583040?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">雷よ大きく広がって飛んでゆけ <a href="https://t.co/hxfm0QclLL">pic.twitter.com/hxfm0QclLL</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340632722822156290?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">紅蓮の雷よ、大きく広がって飛べ <a href="https://t.co/XpFQugY7w9">pic.twitter.com/XpFQugY7w9</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340633876704608257?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">燃えろ燃えろ燃えろ燃えろ燃えろ燃えろ燃えろ <a href="https://t.co/7E1xUNNOjq">pic.twitter.com/7E1xUNNOjq</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340686256645148674?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">雷雷雷雷紅蓮の炎をまとって飛べ <a href="https://t.co/Byt6PGCTGT">pic.twitter.com/Byt6PGCTGT</a></p>&mdash; 玉露 (@ororo33) <a href="https://twitter.com/ororo33/status/1340688984121327617?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 使用したもの
[Unity(2018.4.01f1)](https://unity3d.com/jp/unity/whats-new/2018.4.01) : ゲーム開発エンジン
適当なマイク
Ginza:自然言語処理用のライブラリ
UnityEngine.Windows.Speech:Windowsが提供している音声認識ライブラリ
（VR上で体験したいなら）Oculus Linkを使用したOculus Quest（公開しているアプリはVR非対応）

# 構成図
システムの仕組みは以下のようになっています。
Userが唱えた魔法をUnity経由でpythonで書かれた自然言語処理用のサーバーに送信。
サーバーで唱えられた言葉の名詞・動詞を抽出して分散表現に変換。
あらかじめ分散表現を学習させたモデルを使用して予測することで、発動する魔法の種類や動作を予測。
その種類や動作に応じた魔法をUnity上で発動させます。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315420/2682e23e-2216-5f93-8928-a5a41d84d859.png)

# 魔法の仕組み
今回作成した魔法のシステムは属性と動作の二つの要素で成り立っています。
属性：炎、氷、雷の三種類
動作：まっすぐ飛ぶ、広がるの二種類
これらの要素が詠唱した内容にどれだけ含まれているか、で発動する魔法が変わります。

例えば`燃えろ`だと燃えろ、が属性：火、動作：なし、となるため、目の前に炎が生成されます。
`ファイヤーシュート`だと`ファイヤー/シュート`と分割され、属性：火、動作：まっすぐ飛ぶになるため、目の前に炎が生成された後まっすぐ飛んでいきます。
この属性と動作は一つの要素だけとは限りません。
`雷よ大きく広がって飛んでゆけ`だと属性:雷、動作:まっすぐ飛ぶ＋広がるになるため、雷が拡散しながらまっすぐ飛んで行くという動作になるし、`紅蓮の雷よ、大きく広がって飛べ `だと属性:炎+雷、動作:まっすぐ飛ぶ＋広がるになるため、炎と雷が混ざり合いながら拡散して飛んでゆきます。
`紅蓮の炎よ、稲妻のように燃え盛り大きく広がって飛べ`、とかだと属性:炎+炎+炎+雷、動作:まっすぐ飛ぶ＋広がるになるため、大きな炎と雷が混ざり合いながら拡散して飛んでゆきます。（めちゃくちゃ詠唱が難しい。この魔法の詠唱に成功したことはないです。）

今回はデモのため属性と動作を少なめで作りましたが、実際にはこれらの要素を増やすことで、無限のパターンの魔法を作成することができます。
例えば動作に「ランダムに飛ぶ」「二つに分裂する」などを増やしたり、物質特性のような要素を増やして、詠唱によって魔法が壁にぶつかって跳ね返るようになったり重力の影響を受けるようになったりすることもできます。
色々言葉を変えることで、その時々で自分の望む即興の魔法を生み出し、使うことができる。
これぞ魔法、という感じがしますね。
またこの魔法は動作がなくても成立しますが、属性がないと成立しません。
そもそも動作される対象が生成されないからです。

また、魔法に反応しやすそうな言葉はダウンロードしたファイルのelement.csvに書かれているので、参考にしてください。
反応してほしい言葉の種類を増やすこともできます。

# 使い方
## 1. 以下のページからコードをダウンロード
https://github.com/gyokuro33/ChantMagick

## 2. 以下のコマンドをPowerShellで実行することでライブラリを追加
```
pip install Flask
pip install sklearn 
pip install csv
pip install numpy
pip install "https://github.com/megagonlabs/ginza/releases/download/latest/ginza-latest.tar.gz"
```
## 3. 以下のコマンドでNLPServer.pyを起動
```
python .\NLPServer.py
```
## 4. UnityApp内のChantMagick.exeを起動してかっこいい詠唱をすると良い感じに魔法が使える

以上の操作でアプリを使用可能です！
詠唱に使用する言葉はダウンロードしたフォルダ内のelement.csvを参考にしてください。
こういう種類の言葉が欲しいよ！　というのがあればその言葉をクラスと一緒に追加してください。
クラスと魔法の効果の対応は以下の通りです。

```
1:炎
2:氷
3:雷
4:まっすぐ飛ぶ
5:広がる
```

# まとめ
今回は即興魔法を使えるようなシステムを作ってみました。
実際作ってみると、魔法を自分の自分の思いつくままの言葉によって使うことができるというのは非常に楽しい経験でした。
実際音声認識に言った言葉を認識させるのはけっこう難しくて、ああ、こんな風にはっきりとした活舌で言わないといけないなら戦闘中に魔法を失敗するのも分かるな、とか。
その場で即興で魔法使うの難しいから、あらかじめ決められたワードの詠唱を練習してみんな使っているんだろうな、とか。
とても面白いので、今度はもっと魔法の要素を増やしたうえで、VR上で対戦ゲーム的に魔法を使って競い合うゲームを作ってみようかな、とか思ってます。
その時々で即興で作成した魔法を打ち合うとか面白そうです。
今回は同じワードでも属性は累積していくように作っていましたが、同じワードは累積しないように作るとゲーム性が出てきたりするかなとか思ったり。
以上です。
ぜひみんなも自分だけのオリジナルスペルを作って楽しもう！