VRChatでSnailMarkerをEmoteSwitchで出し入れしつつハンドサインを残したまま実装する方法

VRChatのアバターに指先ペンを実装したくて四苦八苦していたのでここに記します。
具体的には、SnailMarkerをEmoteSwitchで出し入れできるようにしつつ、
ハンドサインを残したまま共存させる方法です。

#EmoteSwitchのしくみ

EmoteSwitchは傘や楽器のような3Dモデルを、エモートを使って出したり消したりできるようにするツールです。
このツールが何をやっているかというと、
「エモートのAnimationでObjectのActivate/Deactivate」をしています。

Unityでは傘や楽器、アバターなどの3Dモデルは「Object」として定義されます。
（3Dモデル以外も全部Objectに抽象化されるけど、詳しい話は割愛）
そしてすべてのObjectには「有効/無効」が設定でき、無効なObjectは表示されなくなります。
この設定が「ObjectのActivate/Deactivate」です。

一方でObjectには「Animation」を設定できます。
Animationはその名の通り、Objectの「動き」を定義するもので、
例えばエモートはAnimationによって、アバターモデルの各関節の「動き」が定義されています。

Animationには関節の動作のように目に見える「動き」以外にも、
Objectの有効/無効の設定を行うことができます。

EmoteSwitchでは、エモートのAnimationにObjectのActivate/Deactivateを設定することで、
エモートで3Dモデルを出したり消したりできるようにしています。


#SnailMarkerのしくみ

SnailMarkerは空中に文字や絵を描けるようになるアセットです。
このアセットが何をやっているのかというと、
「ハンドサインのAnimationでTrailRendererの位置と描画秒数を設定」しています。

TrailRendererとは、Objectの移動の軌跡を描くことができるUnityの機能です。
この機能を設定することで、指定したObjectに指定した色の軌跡を描かせることができます。
SnailMarkerでは、指先やペン先にTrailRendererを設定し、
軌跡が消えるまでの時間を120秒に設定することで、
軌跡を長時間その場に留め、文字や絵を描けるようにしています。

ただし、それだけだと指先やペン先から常に軌跡が出続けてしまいます。
そこで、軌跡を一旦止めたいときには10万m遠方にTrailRendererを移動させ、
軌跡をすべて消したいときには「軌跡が消えるまでの時間」を0秒に設定することで、
軌跡の停止や削除を行っています。

SnailMarkerはこの軌跡の操作をAnimationを用いて行っています。
「Drawing」Animationを再生中のみTrailRendererの位置を手元に戻し、
「EraseAll」Animationを再生中は「軌跡が消えるまでの時間」を0秒に設定します。

#本題：実装方法

以下の順序で実装を行います。
1.SnailMarkerのMarker/TrailPosition以下をEmoteSwitchでエモートに登録
2.SnailMarkerの設定を追加したAnimationを作ってハンドサインに登録

##1.SnailMarkerのMarker/TrailPosition以下をEmoteSwitchでエモートに登録

以下のページを参考に進めましょう。
補足として、ペンの3Dモデルが欲しい場合は「Marker」プレハブを、
指先で線を引きたいを場合はMarker内の「TrailPosition」を、
アタッチしたいボーンに設定します。

[【VRChat】エモートスイッチを使って物を出す方法！！](https://keiki002.com/vr/vrc-es/)
[【VRChat】Snail Markerを使って指にペン機能を付けてみよう！！](https://keiki002.com/vr/snailmarker-pen/)
[エモートスイッチでペンを出し入れする方法](https://scrapbox.io/nukora/%E3%82%A8%E3%83%A2%E3%83%BC%E3%83%88%E3%82%B9%E3%82%A4%E3%83%83%E3%83%81%E3%81%A7%E3%83%9A%E3%83%B3%E3%82%92%E5%87%BA%E3%81%97%E5%85%A5%E3%82%8C%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)



##2.SnailMarkerの設定を追加したAnimationを作ってハンドサインに登録

SnaiMakerで作成された「Drawing」「EraseAll」の役割を持つAnimationを作成し、登録します。
「Drawing」「EraseAll」を編集してもかまいませんし、新しくAnimationファイルを作成しても構いませんが、
SnailMaker用の設定を維持する必要があります。

Animationの作成・編集・ハンドサインへの割当については下記ページを参考に進めてください。
 Animationの作成
 [アニメーションオーバーライド](https://vrcworld.wiki.fc2.com/wiki/%E3%82%A2%E3%83%8B%E3%83%A1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%A9%E3%82%A4%E3%83%89)
 Animationの作成・編集・ハンドサインへの割当
[アニメーションオーバーライドを入れてみよう！！(物・手編)](https://keiki002.com/vr/anime-obj/)

SnailMakerで必要なAnimationのPropertyは以下の2つです。

TrailSource:Position
「Drawing」に設定されるべきPropertyです。
TrailRendererの位置を10万m遠方から手元に引き戻します。
Positionのx,y,zをいずれも全てのフレームで0に設定しましょう。

TrailSource:Trail Renderer.Time
「EraseAll」に設定されるべきPropertyです。
TrailRendererの軌跡を残す時間を0に設定します。
すべてのフレームで0になるように設定しましょう。

なお、VRCSDK/Expample/Animation/Male_Stand_Pose.fbx内に登録されているハンドサインのAnimationは、
どういうわけか全てIdleの状態で保持されているようです。
人差し指で線を引きたいなどの場合には、自分でAnimationの各Propertyの値を設定しましょう。

Animationは操作によっては編集できなくなるときがあります。
下記ページを参考にしてください。
[【Unity】AnimationClipの編集が出来ない時の対策](http://tsubakit1.hateblo.jp/entry/2018/07/03/233000)


#おわりに
EmoteSwitchとSnailMakerの仕組みを理解するのに半日かかったので備忘録として書きました。
仕組みがわかればリカバリもしやすいので、それもあわせて。
EmoteSwitchはやってることは単純なので、色々と応用できそうです。
でも…あと数ヶ月もすればAvater3.0がやってきてこの記事も陳腐化するんやろなぁ…（遠い目）