Godot EngineでVRMにモーションさせてみる

# はじめに

ゲームエンジンのGodot Engineを以前より勉強しはじめて、勉強したり他の方から教えていただいた使い方を、忘れないように覚え書きとして掲載する。

自分はUnityで [VRMViewMeister](https://sites.google.com/view/lumis-vroidbase/pubcontents/vrmviewmeister) というアプリを作っている。VRMやその他オブジェクトを簡単にポージングやモーションを作って動かせるアプリだ。
かの有名なMMDを目標に作っている。

Unityの件のあの騒ぎ以前にGodotは知っていたが何を作ろういうアイデアも思い浮かばなかった。そこであの騒ぎである。だったらVRMViewMeisterをGodotでも作ってみようかなと考えた。

そのためにはUnityでできていた機能がGodotにあるのか、どのくらいできるのかを調べる必要があり、今回のこの記事もその一環で試してわかった機能である。

※Twitter(現X)で教えていただいた方々には非常に感謝しております。


# VRMをGodotで扱う

## アドオンを追加する

GodotでVRMを読み込む必要がある。それには V-Sekai様の次のアドオンを使用する。なお、この段階までにGodotをインストールしていて、プロジェクトを作成した前提とする。

[godot-vrm](https://github.com/V-Sekai/godot-vrm)

1, Git Hubからクローンしたgodot-vrmのフォルダのうち、次の２つを自分のプロジェクトのaddonsフォルダにコピーする

* addons/vrm
* addons/Godot-MToon-Shader

※リポジトリで注意されているように、フォルダ名は変えずにコピーすること

2, プロジェクトメニューから **プロジェクト設定** をクリック
3, プラグインタブをクリック
4, **MToon Shader** と **VRM** にチェックを入れて有効化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/f61ef307-1e8e-0575-fee8-9d2e3a44f504.png)


## VRMを読み込む

アドオンを入れたら、今度はVRMをプロジェクトに追加する。

1, 好きなVRMを用意し、プロジェクトフォルダに入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/83c7b6f7-3208-d068-4f07-bfe91628c9d2.png)

2, VRMファイルを右クリックし、 **インスタンス化** をクリックしてシーンに追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/57fae48b-2e68-f0c9-0dc8-f7f14f4879df.png)

※VRMがビューの中に表示されたことを確認する。

これで読み込みはOKだ。GodotでもVRMを簡単に使えるようにしてくれたアドオンの作者様に感謝。

# VRMのモーション

## ボーンを確認する

VRMをメインのシーンに追加したら、このようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/aa5ce58d-0a98-c69d-a852-e39466d89481.png)

1. ここで次の２つの種類のノードがあるか確認する

* GeneralSkeleton (Skeleton3D)
* AnimationPlayer (AnimationPlayer)

godot-vrmの古いバージョンやVRMの作りによっては名前やノードの階層構造が若干異なるかもしれない。

2, GeneralSkeleton ノードをクリックし、インスペクターを確認する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/b2fa64df-3504-b43f-fe80-472e7136d547.png)

このように、右のインスペクター上にVRMが持つボーンの階層構造が表示される。

:::note info
※Unityでは...
UnityではVRMのヒエラルキーの中に直接Root→J_Bip_C_Hipsや Vrm10ControlBone:Hipsなどのように階層構造が展開されていた。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/ff13416a-e933-73e6-e107-e57bd5bc60ba.png)

Godotだとノードではなく、あくまでSkeleton3DのBonesの中で階層構造として展開されるようだ。

## VRMにアニメーションを追加する

1, 対象のVRMの **AnimationPlayer** をクリックして選択する
2, 下部のパネルにある **アニメーション** タブをクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/04a22a53-2789-5bc9-9932-4c032eb91293.png)

3, アニメーションボタンを押し、 **アニメーションの管理** をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/7bd02232-90da-4865-acca-3816218169fc.png)

4, 新しいライブラリ をクリック
5, 名前をつける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/997c6dc9-1e75-d89b-9444-1049cf596055.png)

標準で用意されているブレンドシェイプ（エクスプレッション）以外の任意のモーションを分けて作りやすくなる。

6, ライブラリ名の行の右にある **＋** ボタンを押す
7, アニメーション名をつける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/091373bf-86b0-d5fa-6d9c-fb2f444cd7dd.png)

これで新しいモーションを作れるようになった。このアニメーションはまっさらな状態なので、これから自由に登録できる。

## VRMの動きをキーフレームに登録する

1, アニメーションタブに戻り、先程作ったアニメーション名を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/e3860656-8be2-03a6-bb5a-de5fb06c6e01.png)

トラックが全くない状態である。

2, タイムラインの右の方にある入力ボックスにて、アニメーションの全体の長さを設定する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/67b6f4d5-7b85-8ec8-79aa-8bfdfc8a5230.png)

3, Timeが0の位置に現在のTポーズの状態を登録する

3.1, GeneralSkeleton をクリック
3.2, ビューの上のツールバーにある **キーの挿入(全てのボーン)** をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/f88f5d4e-9099-6933-30eb-a6d76e309f7a.png)

3.3, 確認が出るので **作成** ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/a02259e0-be87-f7ed-6330-4b178bce202d.png)

今回はTポーズから動かす例なので、3. の手順は目的に応じてカットしてもいいと思う。

4, 目的のTimeの位置に変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/95e6df0f-087b-f310-34ce-50e9ed64ff5e.png)

5, VRMを動かしていく

### 方法1：Skeleton3Dのbonesの一覧でPositionやRotationを直接指定する

1, 動かしたいボーンを選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/ebb13fa7-66d2-ef04-e673-5f8c17e6ff79.png)

2, bones一覧の下にある各入力ボックスを変更する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/cfb8ad00-191c-4336-6c27-5331eb9af853.png)

3, プロパティ名の横にあるキーマークをクリックする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/ec74ec1d-2a27-afe8-ae6a-758ee291b104.png)

<dl>
<dt>Position</dt>
<dd>3Dポジショントラックが挿入される</dd>
<dt>Rotation</dt>
<dd>3D回転トラックが挿入される</dd>
<dt>Scale</dt>
<dd>3Dスケールトラックが挿入される</dd>
</dl>

その他のプロパティはおそらく キーマークをクリックしたときにプロパティの種類に応じて自動的に適切なトラックが挿入されるようになっているようだ。

:::note warn
VRMなど複雑なボーンを持つモデルは、この方法だと直感的ではなく大変だと思われる。
:::


### 方法2：Skeleton3Dの編集モードを使ってVRMを直接動かす

1, 対象のVRMの **GeneralSkeleton** をクリックする
2, ビューの上のツールバーの **編集モード** をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/f9e0b0d9-f5ea-858d-8318-b80d990f8044.png)

VRMのボーンと同時に青い点が表示されるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/c98ae2f6-daa1-0c6b-a863-ab99370e27e8.png)

インスペクターのbonesの一覧と連動しているので、どこを動かすのかわかりづらかったらbonesの一覧で目的のボーンをクリックすると、Transform handleが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/a0f5dc45-6f1c-6549-bf3c-4dba363b1b46.png)

3, 目的のボーンを移動したり回転する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/2cbed523-43f3-ac26-6563-d9f9020444d6.png)

4, プロパティ名の横にあるキーマークをクリックする

この方法だと本当に特定のボーンの特定のトランスフォームだけをキーフレームに登録できる。

※別の方法
ビューの上のツールバーの **(既存のトラックに)キーを挿入** をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/ac8b54ad-aad4-a987-49b0-0e8d8883f9d7.png)

これをすると存在するトラックすべてに対して、現在の位置・回転・スケールなどのプロパティの状態を登録してくれる。

## 再生する

実際に再生して確認してみる。
再生はAnimationタブ内にある 再生ボタンを押す。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/88634b9a-154a-d876-06ca-a138ab1a1b46.gif)


## モーションをファイルに保存する

1, Animationタブで **アニメーション** ボタンを押し、 **アニメーションの管理** をクリック
2, 右の方で ストレージ列の端にある 保存ボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/44889e7d-afe0-2b6d-bd6a-2b4c1b980b7c.png)

3, 名前をつけて保存をクリック
4, ファイルダイアログにて、任意の形式でアニメーションを保存する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/585d388c-4661-a031-d0bf-c9e0ef8793e6.png)

:::note warn
.anim形式はおそらくUnityの同名の形式とは異なるので注意。
:::


## 別のVRMにモーションを登録する

1, 別のVRMの **AnimationPlayer** をクリックする
2, Animationタブで **アニメーション** ボタンを押し、 **アニメーションの管理** をクリック
3, 目的のアニメーションライブラリの右にある 開くボタンを押す

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/9c8f6a72-8422-097e-4ef4-e74800c7295d.png)

4, 目的のアニメーションファイルを選択して開く
5, アニメーションライブラリにアニメーションが登録されたことを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/68ec1b26-1477-fd0a-12af-2988bc838a05.png)

:::note info
ファイルから登録された場合、ストレージ列は ファイル名になる。
:::


# 終わりに

ここまで、Godotにおけるアニメーションの扱いを見てきた。自分は実際に弄りながら四苦八苦していたので、Twitter(現X)上でお詳しい方に教わったことを忘れないうちにまとめようと思った次第である。

UnityのAnimationの各パネルや実際にモーションを作り出すまでの工程に比べると、 **個人的には** 非常に直感的でわかりやすく、工程も少なく取り組めたと感じた。

一度作ったアニメーションを別のVRMに割り当てるのも、パネル内のメニューを見てすぐに想像つくくらいわかりやすくできた。

ここまでできるならGodotのほうがアニメーションを作りやすいのではと思う。
誤解を恐れずに例えるなら、

**UnityのVery Animationアセット＋Unityの標準のAnimationパネル・各機能 = GodotのAnimation機能**

という印象を受けた。
Very Animationもあれはあれでだいぶ作りやすいのだと思うが、実際のところあれで苦戦して断念し、自分がアニメーションを作りやすいツールとして **VRMViewMeister** を作ったくらいなのだ。
ところが同じかはるかに直感的で簡単に、Godotで同程度のことができてしまった。

:::note
AnimationTreeというノードもあるようで、さらにUnityと同程度のことができるらしいが、こちらはまだ勉強中。
:::

最初GodotでVRMViewMeisterを作り直してみるかと思ったけど、標準でこれだけ簡単にできるようになっているなら、拙作アプリは不要だな・・・と嬉しい悩みを抱えることになりそうだ。


この記事がGodot EngineでVRMを扱いたい人の手助けになれたら幸いです。