【VRChat】 boothで買ったアニメーション付きのアクセサリーを自分のアバターに反映する方法

## 前段
boothで買ったギミック付きのアクセサリーなどがいざ自分のプロジェクトにインポートしても、うまく動作しない場合が往々としてあります。
調べてもその内容に特化した記事がなかったので、備忘録も兼ねてその場合の対応と導入手順を記載しておきます。


## この記事で分かること
- アバターに仕込んだオブジェクトの出し入れの方法
- Animationの割り当て方法
- Expression Menuのデバッグ方法
- Animation処理が実行される条件の変更方法
- Gestureギミックの修正方法


## 前提条件
・Unityを使ってアバターをサーバーにアップロードできる人
・基礎的なアバター改変(手順書に沿ってオブジェクトの位置の調整したり基本的なUnity操作)ができる人

## 使うpackage
・[Tabaco and Lighter - 誰でも使えるタバコとライター (PB)](https://booth.pm/ja/items/3954498)
・[VRC Avatar Parameters Integration 0.3.0](https://tearrain.booth.pm/items/2979286)
・[VRCAvatarFXControllerIntegration](https://booth.pm/ja/items/2980972)
・[AnimationValidator](https://github.com/sukedon/AnimationValidator)

これらのPackageをダウンロードしてインストールしておきます。タバコとライターは説明用なので、適宜使いたいオブジェクトに置き換えて下さい。


## 手順
### 1. オブジェクトの位置調整
タバコとライターのオブジェクトのprefabをDrag & Dropして、自分の手の位置に適宜調整します。
この時、ライターは手のArmature（ボーン）、タバコは人差し指のArmatureに入れるようにします。
Armatureに入れないとオブジェクトは体の動きに追従してくれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/4bc54a2e-1a94-a02b-d203-3a3c9155d892.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/dcac1451-0651-9189-e101-0b84986c8797.png)

World Constraintを右の人差し指に入れる。World Constraintはタバコを吸った後に煙を発生させるためのものです。
Constraint Settingsに人差し指のボーンを指定しておきます。
これによって煙の発生源を人差し指のボーンにすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/ca0ed670-9818-915f-bac2-6e03b30e88c2.png)


### 2. オブジェクトの取り出し、収納
タバコとライターを常に手に握りしめておきたい人はそんなにいないと思います。
なので、必要な時だけオブジェクトを表示できるようにします。

#### 2-1. Parametersの確認
アバターの最上位の親オブジェクトを選択し、InspecterからVRC Avatar DescriptorのExpressionのparameterファイルを確認します。
booth等で買ったアバターなら大抵設定済みのParameterファイルがあると思います。
ここでは既にParameterファイルが指定されているかだけ確認して下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/fee1bc7e-54f8-fc14-2f04-9ccc19d07847.png)

#### 2-2. Parametersの追加
[VRC Avatar Parameters Integration 0.3.0](https://tearrain.booth.pm/items/2979286)を使います。
このツールを使うと、boothで買ったオブジェクトが既にParameter設定済みの場合、自分のアバターのParameterと統合することができます。
自分で手作業でParameterを追加したり、統合する必要がなくなります。

Unity メニューの「TearRain > VRCAvatarParametersIntegration」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/90128763-4a7a-8132-bbd7-d010b292dc66.png)

結合先(マスター)のParametersファイルと対象(追加したいParameterが入っている方)のParametersファイルを指定して、結合対象のパラメータに追加したいParameterがチェックされていることを確認して、「結合する」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/74b98ff2-bc5a-c62c-f4b9-608f0d372c5f.png)

2-1と同様の操作をして、自分のParametersに対象のParameterが追加されているかどうかを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/c02e1259-f1a5-2c79-02be-7a6995253bc4.png)

#### 2-3. ExpressionのMenuの設定
ここでタバコとライターを出し入れするためのメニューコマンドを追加します。
ExpressionのMenu追加は手動で行います。
ExpressionのMenuをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/ab9972ff-626d-1559-87d3-dc8be8e5c123.png)

Add Controlをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/9febece9-ee7a-886b-d1b1-49e1c2ed5dcb.png)

ここでMenuのMenuを作成します。(SubMenu)
理由は一つのMenuに8つまでしか登録ができないので調子に乗って色々と追加していくとすぐにいっぱいになってしまうからです。
自アバター以外のMenuを作成する場合は新たにSubMenuを作成する方が、内蔵のMenuと追加Menuが区別しやすくて良いと思います。

Nameは任意の名前を設定します。
Iconは選択しなくても問題ないです。
TypeはSubMenuを選択します。
Parameterは入力不要です。
Sub MenuでMenuファイルを指定する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/dea08396-f4f9-a3c4-0a7a-c7a59c0918bf.png)

ここからSubMenuファイルを作成していきます。
SubMenuファイルを作成する前に、自分の作業が分かるようにAssets配下に任意の名前のフォルダを作成します。ここでは「MyWork」としています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/7193fd5a-0af2-162b-bb07-3d0b60d66a17.png)

「MyWork」フォルダ内で右クリックして、Create > VRChat > Avatars > Expressions Menu を選択してExpressions Menuファイルを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/d244f986-df17-f308-8cf4-12b5df0a302a.png)

ファイル名を分かりやすい名前に変更して、Add Controlボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/254a4f30-3233-0556-1f4b-73dea2a89d1e.png)

MenuのNameを入力します。
Iconは選択しなくても問題ないです。
TypeはToggleを選択します。
Parameterは2-2で追加したパラメータを割り当てます。
メニューを操作することで、設定したパラメータの値を操作するイメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/657704ad-b3a0-db8f-bf31-b75fd4dcbd63.png)

作成できたら元のMenu画面からSub Menuを割り当てます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/ea2bed29-73a0-8786-7ff5-4625a5109285.png)

これでMenuの設定は完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/6978dd53-c1e2-7501-7e5a-3dddc8ba5cb2.png)


#### 2-4. Controllerの統合
このタバコとライターはControllerの設定が既に設定されているので、既存のControllerとの統合を行います。
アバターの親オブジェクトを指定して、FXファイルをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/b4dcae69-b312-82d8-e8a3-fcca1b310699.png)

デフォルトのFXレイヤーが表示されます。ここにタバコとライターのLayerを追加していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/f0f192ce-acad-2eb9-0104-cd8d424cdbca.png)

[VRCAvatarFXControllerIntegration](https://booth.pm/ja/items/2980972)を使います。
2-2の[VRC Avatar Parameters Integration 0.3.0](https://tearrain.booth.pm/items/2979286)のController版です。
Unity メニューの「TearRain > VRCAvatarFXControllerIntegration」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/141057e3-a140-2bc3-c883-db32228717d6.png)

Paramaterの時と同様に結合するControllerと対象のControllerを指定して、「結合する」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/c8684cc5-7a49-cd0b-3738-bcfd4fd22fce.png)

Layerが追加されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/b0bdb2e3-789b-eb4d-2b40-90f9e6afb025.png)

#### 2-5. Animationの統合
タバコとライターのアニメーションをアバターの親オブジェクトにDrag & Dropします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/be703f9c-17b0-538e-aa0c-d84aff5e6864.png)

Animationsウィンドウを開くとAnimationが追加されているのが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/55b0c6cb-b0b5-44cb-21aa-949234f06532.png)

任意のAnimationを開くと、Animationのオブジェクトが黄色文字になってMissing!と表示されているオブジェクトがあると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/926da4ed-1bb8-6832-d8f5-c5c3955b7d37.png)

これはHierarchy上でのオブジェクトの階層が元々のtabacoオブジェクトのAnimationを登録した時の階層と異なることが原因です。
このままだと火をつけるギミックやキャップが動かなかったりします。
解決方法としては今のタバコの入っている階層と同じ階層に再度Animationを登録し直す必要があります。
いちいち手動で割り当てしなおすのは面倒くさすぎるので先駆者の方が作って下さった[【Unity】Animationのmissingを自動で修正するエディタ拡張](https://qiita.com/sukedon/items/71247af4a4494303dc66)を使います。
これを使うと自動でMissingしているオブジェクトを正しいパスに修正してくれます。

アバターの親オブジェクトを右クリックして「アニメーションクリップ修正」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/bc0e62fc-a2fe-a109-488e-12a5f26af361.png)

「全部まとめて修正」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/648e98c5-19db-a436-3e38-9a010bde5c77.png)

「パスを変更しました」と表示されれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/e9a24af6-0f5c-7349-fc7a-3ef96b0c963e.png)

Animationをもう一度開くとMissingが消えています。
これでAnimationの階層の修正は完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/feffa49c-5c75-e65c-e4f5-2d1ebe969ead.png)

GestureのControllerも同様に統合しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/c060fa63-c0f0-85b3-b208-12dfe8321d87.png)

ここまでで一度タバコとライターが出し入れできるか確認しておきます。

Expression Menuの動作確認をUnity上ですることができます。
メニューのTools > Gesture Manager Emulatorを選択するとHierarchyにGestureManagerが追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/872b5984-9870-824e-ac1b-b4127c5a9d80.png)

この状態でUnityを実行するとお馴染みのAction Menuが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/d6db2701-b4a2-fd64-1b4e-66bb0a07521e.png)

VRCと同じように操作するとライターとタバコが手のあたりで表示・非表示ができているのが確認できると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/481fada0-38e8-5e9d-85e8-ac4d4a8bc463.png)

#### 2-6. Animatorの修正
ギミックの動作条件に特に問題がない方は2-5まででいいと思いますが、このタバコギミックは左手のfistジェスチャーでライターをつけた後、タバコに火をつけて顔に近づけて右手のfistジェスチャーをすることでタバコを吸う音が発生します。
その後、Fist以外のジェスチャーをすると煙が出る方式になっています。
個人的にFistでタバコを吸うのは違和感があったので(あくまで個人の見解です。作成者様の設計を揶揄する意図はありません)、顔に近づけて右手のPeaceジェスチャーをすることでタバコを吸う音が発生、その後Peace以外のジェスチャーをすると煙が出る方式に変更していきます。

まず、Gestureがどういった条件の時に発生するのかを確認します。
割り当てられているBase Gestureを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/d86b74d7-66bd-fba2-b8ee-60ae6b931c8b.png)

Right Hand Layerを選択して(Leftでも可)、Layerの中身を見てみると色々なGestureが分岐していることが分かります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/e6e16059-a2dc-9677-1772-6593cf54ef32.png)

例えばFistに繋がっている矢印を選択して、Conditionsを見てみるとGestureRight equals 1の時がFistのジェスチャーモーションを取るということが分かります。

[VRChat Avatars3.0 公式ドキュメント 非公式翻訳 その１ (Animator Parameters)](https://ankoro199.hatenablog.com/entry/2021/04/24/114510)の記事のGestureLeft と GestureRight の値とハンドサインの対応表でも同様の内容が記載されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/0c2227f1-2079-3ba0-42ef-62402f80bb68.png)

今回だとPeaceのジェスチャーをした時に、タバコを吸いたいのでtabaco soundがOnになる条件をGesture Right Equal 1を1から4に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/9f8848a8-e970-2cc5-6e74-bb76c8b781d9.png)

また、tabaco soundが消える条件もGesture Right NotEqual 1から4に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/1b3cd776-231b-e76c-9047-610b3c428f89.png)

tabaco smokeも同様に変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/f40d2a99-230e-cc3d-cd9e-0f4c42f7ebdf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/7dc921cd-ae61-2002-4838-07b8a72a6ae7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/3d6f31db-d852-43bd-1ca4-99d3eff218d1.png)

あと、デフォルトの設定のままだとライターを出した状態でFistジェスチャーをするとなぜかライターの蓋が開かずに、火のエフェクトが発生する仕様になっています。
このままだと困るので条件を変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/009aaf7e-8eab-3981-dc27-ee31cab0e0ef.png)

GestureLeft Equal 1から7に変更します。これでFistジェスチャーでライターの蓋を開いて、Thumbs upジェスチャーでライターに火をつけるというギミックになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/98231f09-aea9-07e5-0440-678ea6556a5a.png)

さらにライターの蓋を開けた後に、再度蓋を閉めて更に開けられるようにしたり、ライターの火をつけた後に消したりできるようにもします。

Hand Openジェスチャーでライターの蓋を閉じられるようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/93502bb9-8de8-76bb-9074-8e767003ac03.png)

火をつけてからThumbs upジェスチャー以外のジェスチャーをすることで火を消すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/c8bd6d1f-ea4f-cb64-dc5a-a2bce06df0ea.png)

これでアバターをサーバーにアップロードすれば完了です！

## ※トラブルシューティング
### 2-5. Animationの統合してMissingが消えたのにアニメーションが動かない
A. 
AnimationValidator赤線のpathを自動で修正してくれるのだが、Animationファイルの中身を確認すると一部パスが変更されていない、AnimationClipがあった。
これらのpathは2枚目の画像のように手動で直す必要がある。
恐らくAnimationValidatorのバグだと思われる。(詳しく調べていないので正しい原因は知りません)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/7ff70617-e4d4-4b0b-14ab-8a65de4bf8ac.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427154/604986f9-4353-b6d5-9efb-1bd2375fd152.png)


## 参考文献
・[【Unity/VRChat】アニメーションのMissing もう恐れる必要はない](https://note.com/efk/n/n7f1dd87c2c4b)
・[【Unity】Animationのmissingを自動で修正するエディタ拡張](https://qiita.com/sukedon/items/71247af4a4494303dc66)
・[VRChat Avatars3.0 公式ドキュメント 非公式翻訳 その１ (Animator Parameters)](https://ankoro199.hatenablog.com/entry/2021/04/24/114510)