GodotIKを試した

# はじめに

　以前より、VRMやその他3Dオブジェクトの簡単便利なアニメーション作成ツールとして、VRMViewMeisterをUnityで作ってきた。
 　以前のUnityのライセンス騒動をきっかけとしてGodot Engineに注目し、GodotでもVRMViewMeisterを再現できないかいろいろ調べて試してきた。

  今回もそんな試行錯誤の一環として、新たに試したGodot Engine用のアドオンがある。
  その名も・・・

  **GodotIK**

  である。


# GodotIKとは？

GodotIKとは、Godot Engineで使えるIKシステムである。といっても名前からあふれる公式感で間違えやすいが、有志の作ったアドオンである。

https://github.com/monxa/GodotIK

Godotの標準のIK（とくに3D）はあるんだかないんだかよくわからず、あまり出来も良くなくまだ改良中の気配があるので、あまり使えそうにない。

自分はVRMをUnityのAnimator標準のIKのように自由に動かせればそれでいいのだが、Godot標準のIKでは満足いく実装ができそうになかった。
そこで調べていて発見したのが **GodotIK** だ。

# GodotIKの導入

まずは公式リポジトリにアクセスする。
書いてあるとおりなのだが、多分パッと見ではプロジェクト導入時に混乱するので書いておこう。

1, 以下からダウンロードする。

https://github.com/monxa/GodotIK/releases

2, 解凍すると次のようなフォルダ構成になっていることを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/24890ea6-2092-4b53-b1a8-7bea6695c891.png)

実際に自分のプロジェクトで使用するのは、`addons` 以下の `libik` フォルダそのものだけだ。

3, `libik` フォルダを自分のプロジェクトの `addons` フォルダにコピーする。

4, Godotのプロジェクトではこうなることを確認する。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/9112ae7b-21cd-4380-88c7-7a4401296964.png)

ちなみにアドオンでよく見かける `plugin.cfg` `plugin.gd` は存在しない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/6d1869cf-fbd0-4ee4-9846-8ccd350c649c.png)

そのため、プロジェクト設定のアドオンの一覧には出てこないので注意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/d4112dbe-9530-47bf-8a92-74e8d8b8a540.png)

# GodotIKをVRMに設定する

VRMをシーンに追加して読み込んだら、`編集可能な子` にチェックを入れてツリービューを展開できるようにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/aadf62db-95e8-4b2d-ac81-0aca8592d1f5.png)

そうしたらVRMのルートノードにある `Skeleton3D` ノードを選択し `子ノードを追加` する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/a1b3b571-c2cc-4d78-ae77-75f999566b2a.png)

前述の通りアドオンとして出てこないが、ノードの一覧にはしっかり出てくるので問題ない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/50271c05-adfb-4c01-a1c5-f15bb48c42d4.png)

VRMに対して追加すべきは次のノードだ。

* GodotIK
* GodotIKEffector

最低限の使用としてはこれで十分だ。

1, まずは `GodotIK` をVRMの子ノードとして追加する。
2, GodotIKの子ノードとして今度は `GodotIKEffector` を追加する。

するとこのようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/1100c5d3-6dd4-4396-a7d0-6d72058102e0.png)

## 別パターン

別のやり方として、 `GodotIKRoot` を使う方法もある。
`GodotIKRoot` は公式リポジトリだとこのように説明されている。

>GodotIKRoot An alternative root node, under which effectors and constraints can be placed. Links into GodotIK through a Nodepath refernce.

通常だとGodotIK配下にしかエフェクターとコンストレイントを配置できないが、この `GodotIKRoot` を別のノードにおいておくと、そっちにもエフェクターとコンストレイントを配置できるようになる。

つまり、こういうことだ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/daf2d598-e3d8-433a-98b4-775f17a1b110.png)

`GodotIKRoot` 側に、`IK Controller` なるプロパティがある。それに `GodotIK` を指定すると、リンクするようになるのだ。

これにより、`GodotIKEffector` や `GodotIKConstraint` 自体をVRMの子ノード（孫ノード）として置いておく必要がなくなる。ノードの取り回しが自由になるのだ。


# GodotIKの設定

ノードを追加したら、プロパティを変更していく。


1, GodotIKEffectorに紐づけたいボーン名を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/e7d0fdf5-e3fa-4ca5-9dc6-3fd65ead42d5.png)

VRMの手や頭など動かしたい部位１つに付き `GodotIKEffector` 1個となる。

Bone Name - 動かす対象のボーン
Bone Idx - Bone Nameを選択すると自動的に選択される
Chain Length - 動かす部位によって、ボーンがいくつ連動するのか指定する。

## Transform Modeについて

このTransform Modeが一番重要だ。これにより、IKの挙動が決まる。
実際にはこれにRemoteTransform3Dを紐づけたりして動かすかもしれないが、直接的にはこの `Transform Mode` のプロパティがすべてを決める。

説明だけだとわかりづらいので動画を用意した。

https://youtu.be/zfX9u2rOmmI

|Property     | Description |
| ------      | ---- |
|Position Only | 部位の回転自体はデフォルトのままで、移動だけ行う。角度自体がそのままなので移動させれば部位の回転が変わる。 |
| Preserve Rotation | 部位のデフォルトの回転を維持し、移動だけを行う。親のボーンの回転が維持されるので、手や足首を動かしたい場合に適している。動画参照。|
|Straighten Chain | 部位の回転を維持し、移動だけを行う。Preserve Rotationと似ているが少々違う。動画参照。|
| Full Transform | エフェクター側で回転するとちゃんと部位も回転する。移動と回転すべてを操作できる。|

スクリプト中でいつでも変更できるので、このあたりは導入するアプリによって使い分けるのが良いだろう。


## さらに踏み込んだ操作

例えばアプリ内でトランスフォームハンドルを使ってVRMを動かすような場合、エフェクターのままではなく、別に3Dオブジェクトを配置し、それに対して操作するとエフェクターも動くような仕組みが良いだろう。

例えば、CSGBox3D（基本的な図形）を配置し、それに `RemoteTransform3D` を子ノードとして追加する。`RemoteTransform3D` の `Remote Path` プロパティに任意のエフェクターを紐づける。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/d6f88dca-0cb2-4b5c-ac44-e76059e0e757.png)

そして `RemoteTransform3D` を子どもに持つ CSGBox3Dをトランスフォームハンドルのアドオンで動かすようにする。

すると `GodotIKEffector` を通じ、VRMの対象の部位が動くようになる。
図にするとこんな感じだ。

```mermaid
flowchart LR
  subgraph VRM
    bone[Bone]
    godotik[GodotIK]
  end
  subgraph othernode[OtherNode]
    subgraph godotikroot[GodotIKRoot]
      godoteff[GodotIKEffector]
    end
  end
  subgraph csg[CSGBox3D]
    remote[RemoteTransform3D]
  end

  bone <---> godotik <---> godoteff <---> remote
  
```

少々手順が必要な仕組みだが、VRMのノードに集約させるよりもあとで修正が効きやすいだろう。

`RemoteTransform3D` を使うことで、操作の末端たるこの部分でPositionやRotationなどを個別に操作オンオフできるので、より細かい取り回しがしやすくなる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/07eca70e-1c54-4476-a5ff-28c9b3cb439d.png)


# 動かした結果

Godotの内臓のIK（SkeletonIK3D）だと苦労した、手を動かしたあとに肘を動かして手の角度を後から変更する。
といった、UnityのFinalIKやAnimatorのIKでは当たり前にできていたことが、ようやくGodotでも実現できるようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38416/50a3a1b4-0a4d-42d4-9756-f78cf455f0e2.png)

あとは `GodotIKEffector` を親子関係にして動かす単位を工夫すればさらに違ったIKの挙動を実現できるだろう。

なお、`GodotIKEffector` を子どもに持つ `GodotIK` や `GodotIKRoot` 自体を動かすと、すべてのエフェクターが同時に動く。
VRM自体は動かないので、VRM自体にも `RemoteTransform3D` を紐づけてあげてうごかせばさらに便利に操作できるかもしれない。


# 終わりに

今回は GodotIK を見てきた。
まだまだ開発中とのことらしいが、現状でも個人的な用途としては十二分に活用できると判断した。
素敵なアドオンを開発してくださってとても感謝している。
ぜひ皆さんの活用の参考になれば幸いである。

あと、ついでに宣伝。
もしGodot でトランスフォームハンドルをお探しの方がいれば、拙作のアドオンもぜひ試していただければと思う。

https://github.com/nishlumi/transform_ctrl_gizmo

ハンドルの形状はクセが強いものがあるのでぜひ改良等自由に加工していただければと思う。

なお、今回テストで作ったプロジェクト一式のリポジトリは下記に置いたので参考にしていただければ幸いである。

https://github.com/nishlumi/godottest01

※VRMやfbx等はすべて自作のものです。