Expression Menuで任意のAnimationを再生する[VRChat Avatars 3.0]
今回は知識編です。
Animation ControllerとExpression Menuの仕組みと使い方についてです。
これ単体で何ができるというより、色々なものに応用が効きます。
表情変化、小物の取り出し、武器の変形、自爆など…
一見複雑な設定ですが、理屈を理解すればそうでもありません。
習得すればアバターに好きなギミックを追加できるようになるので頑張りましょう
ちなみに、今回Animationの作成方法自体は取り扱いません。
やりたいことによって大きく作り方が変わってくるからです。
また、Float型変数によるAxis Puppetも見なかったことにします。
勝手が違いすぎるので別記事に分けることにします
想定読者
- Avatars 3.0でアバターを上げたことがある
- Unityなんもわからん
- 何かしら再生したいAnimationが用意されているとなお良い
Contents
Expressions Menuに関わるファイル4つ
まずは、最初に見通しを説明します。
Expression MenuでAnimationを再生するとき、関わるファイルは4つです。
使う順番に説明すると、
- Parametersに変数名を定義する
- Animation Controllerに変数を利用してStateを作る
- Stateに予め準備したAnimationを挿す
- Expression Menuに変数の値を変えるボタンを作る
といった感じです。
????
となると思います。
それぞれは下で説明していきます。
これらは特に設定しない場合既定値が読み込まれます。
販売アバターの場合全部もしくは一部が設定済みのはずです。
設定されているファイルは、Scene上でアバターを選択すると
InspectorのVRC Avatar Descriptorで確認できます。
上からそれぞれ、Animation Controller、Expressions Menu、Parametersです。
AnimationそれぞれはControllerの中に入れるのでここには出ません。
正確には、Controllerを挿す位置が4つありますがひとまずFXだけ気にすればOKです。
他の3つは移動やAFKなどの自動的な動きを操作するスロットになります。
ファイル名をクリックするとそのファイルの位置に飛べるので活用しましょう。
新規作成であったり、2.0から移行したなどで未設定の場合には
VRCSDK > Example3の中に初期設定のファイルがあります。
ContollerはAnimationの中のFaceLayerがFXの初期値な気がします。
いっそ、いずれもAssetsの中に右クリックで新規作成できるのでそれを使ってもOKです。
ファイルの種類と場所を特定したところで、次に進みます。
Parametersに変数を宣言する
最初に、Parametersに変数を宣言します。
先ほど特定したParametersのファイルを開きます。
一から作る場合は右クリックしてCreate > VRChat > Avatars > Expressions Parametersです。
こんな感じで既に定義済みのParameterの一覧が出てくるはずです。
ここに新しい変数の名前を入れて、種類と初期値を設定します。
それぞれ自分にわかりやすい名前を設定しましょう。
名前は大文字と小文字を区別します。
日本語の文字は念のため非推奨です。
ローマ字にするなり何なりして、入力ミスしないのとわかりやすさを自分なりに調整します。
名前はなんでもいいのですが、問題は変数の種類ですね。
これらのそれぞれと用途を簡単に紹介していきます。
Int型Parameter
Int型は変数の初期値で、整数値を取ります。
Integer (整数)のIntです。
概ねなんでもこれでできます。
上限値は調べていませんが尋常なアバターで使い切ることはないはずです
後述のBoolとの比較になりますが、3つ以上の状態を切り替えるときに必要です。
代表的なのが表情で、0に真顔、1に笑顔、2に怒り顔…といった風に設定します。
また、武器の形態変化で0が剣、1が銃、3が大剣…などといったことも。
3つ以上の状態を切り替えたい、もしくはその可能性があるならIntにしておきましょう。
Bool型Parameter
Bool型は真(True)と偽(False)の2つの状態のみを持つ変数です。
Booleanの略とのことです。
オンかオフしか使う予定がないときに指定すると便利です。
機能上はIntの下位互換っぽいですが、とにかく管理しやすいのが特徴です。
ミスしたときも原因を特定しやすいので、初心者向けかもしれません。
物の出し入れなど、2つしか状態がない場合に使うと便利です。
Falseの間は非表示、Trueで表示。わかりやすいですね
Float型Parameter
Float型は浮動小数を扱える変数です。
主に、Axis Puppetのメニューと合わせて使います。
何かの度合いを指定するなど、滑らかに変化するAnimationに向きます。
例えば、笑顔の度合いを0から100まで設定するなどの表情、
値を大きくした分武器が伸びる、などの使い方ができます。
Animation Controllerも含めて設定方法が変わってくるので今回は無視します。
いずれにせよ管理も大変で最初に扱うには向かないと思います。
定義済みParameterについて
各アバター固有のスイッチを設定する場合、このように変数を宣言する必要があります。
一方で、VRChatにはすでに定義された変数があります。
代表的なのは、GestureRightやGestureLeftですね。
それぞれの手で作っているハンドサインの形を値として扱います。
市販アバターでハンドサインと表情が同期するのはこういうことです。
他にも、ミュートかどうかを受け取るMuteSelfや、
AFKの状態だとTrueになるAFKなどもあります。
これらはParametersに入力せずに、しれっとControllerから参照してもOKです。
GestureRightやGestureLeftを使いたい人はしたがってこの設定は不要です
定義済みParameterの一覧はこちらです。英語ですが
今回は、仮にこちらのゴーグルを出し入れすることにします。
誰が何と言おうとヨルハ部隊式のゴーグルです。
用途を考えるとオンオフのBool型でも足りますね。
ただ、今後に普通の眼鏡と付け替えたりするかもしれません。
拡張性を考えて一応Intで設定していきます(説明の都合)
先ほどのParametersの空欄にわかりやすい名前でParameterを足します。
今回はScannerとしておきます。
大文字小文字の区別に繰り返しですが気を付けましょう。
Defaultの欄は変数の初期値を設定することができます。
別に変える必要はないと思います。
元々出ているものを消したいとき(服を脱ぐとか)で1やTrueを初期値にすると綺麗なのか…?
Savedをオフにすると、再起動やワールド移動で値が初期値に戻るらしいです。
正直上手い使い道がわからないので放っておいていいと思います。
設定が終わったら、Animation Controllerに移ります。
Animation ControllerにStateと遷移を作る
次に使うのは、Animation Controllerです。
新しく作る場合は、Create > Animation Controllerです。
Controllerで利用する変数を追加する
まずは、Controller上で使うParameterを追加する必要があります。
Controllerを開いた後Parametersのタブを開き、追加を行います。
右上の+からまずは変数の型を選択します。
今回の例ではIntにしましたが、Boolの場合はそちらを選んでください。
変数が作成できたら、名前を一文字も違わずに入力します。
スペルミスや大文字小文字の違いで全く動かなくなります。
やってみて動かなければ確認することの一つでもあります。
逆に、Parametersの方でスペルミスしていることもあります
右側の欄もまた初期値だと思いますが、触らないでおきましょう。
Parametersの方と初期値が競合した場合の挙動はちょっと保証できないです
この工程は、前述の定義済みParameterでも必須です。
Parameterや次のExpressionsMenuはVRChat側の提供しているものですが、
このAnimation ControllerはUnity側の機能なので、勝手にVRC側の変数は読んでくれません
(初期値の欄が重複しているのもおそらくそういうこと)
Animation ControllerにLayerを追加する
次に、ControllerのLayerタブに戻ってレイヤーを追加します。
先ほどのParameterの追加と同様に右上の+を押します。
レイヤーの名前を入力することになりますが、こちらは任意の名前でOKです。
自分にとってわかりやすい名称を設定しましょう。
今回はFaceItemにします。今後に眼鏡を足すかもしれないので
次に、右側の歯車マークをクリックしてWeightを1にします。
これを行わないとAnimationが動きません。
よくある設定忘れの1つなので気を付けましょう
なお、既存のレイヤーに追記することももちろん可能です。
今まで使っていなかったジェスチャーに表情を割り振るなどですね。
ただし、Animationの系統ごとにレイヤーを分けるのを強く勧めます。
なぜなら、各レイヤーに設定されているAnimationはそのうち1つしか再生できないからです。
そのため、例えば表情と小物を同じレイヤーに入れた場合、
小物を出している間表情を変えられないみたいなことになります。
小物同士でも同じことです。
武器と眼鏡を同時に出すつもりがあるなら、レイヤーは別にすべきです。
逆に、表情同士や「左手に持つ物」など一度に一つしか出さない場合は
同じレイヤーにすることで混線事故を防げたり、設定がきれいになったりします。
また、同じ値を再生するAnimationが別レイヤーにある場合、
上のレイヤーにあるAnimationの値が優先されます。
特にこれの影響を受けやすいのが表情関係です。
例えば、ExpressionsMenuから発動する表情をハンドサインより優先したい場合
そちらのレイヤーを上に置いておく必要があります。
まあそのあたりの細かいことは個別の記事で説明するかもしれません
Animation ControllerにStateと遷移を設定する
ここから、Animation Controllerの根本的なシステムに触れます。
Controllerの各レイヤーにはState(状態)があり、すごろくのマス目のように
今の状態(自分のコマ)が指示通りに進んでいきます。
このマス目同士を、遷移(Transition)の矢印でつないでいきます。
サイコロの目で1以上が出たら移動、みたいな感じに条件付けします。
矢印がつながっていないところには移動できません。
さて、まずは新しいレイヤーにStateを追加します。
何もない中央当たりで右クリックして、Create State > Emptyします。
オレンジ色のNew Stateができ、Entryから勝手に矢印がつながります。
これは、Entry(アバターが読み込まれたとき)に最初に再生される特別なStateです。
たとえるならスタートのマスです。
このStateは、勝手に再生されることになるのでふつうは空のままにしておきます。
活用する方法もありますが応用になるので今回は放置します。
もう一度同じ操作をして、灰色のNew Stateを作ります。
今度は、何も矢印がつながっていない灰色のStateができました。
Inspectorからわかりやすい任意の名前に変更します。
今回はScanner Onとしました。
そうしたら、このStateに向かう矢印を引きます。
オレンジのNew Stateで右クリックして、Make Transitionを選びます。
繋げる先のStateをクリックすると、矢印がつながります。
そうしたら、この矢印を移動するための条件を書き込みます。
矢印を選択してInspectorを見ます。
まずは、一番下のConditionsの+を押します。
これによって、この矢印上を移動するための条件が設定できます。
ここで、Parameterのタブに書き込んだParametersの一覧が表示されます。
Greater(以上)、Less(以下)、Equals(等しい)、NotEqual(等しくない)が選べます。
今回は、Scanner Equals 1 としました。
Scannerパラメータが1になったとき、矢印の通りに移動します。
また、上にあるHas Exit Timeを外しておきます。
これは、前のStateが任意%再生されたら勝手に移動するという設定です。
勝手に移動すると最初は意図しない動きになりがちです。
活用法もありますが例によって最初は外すのが安定です。
こんな感じになりました。
これで、Scanner Onのマスに進むための準備はOKです。
ですが、このままでは問題があります。
これだけだと最初の状態(ゴーグルが出ていない状態)に戻れません。
表情で言うなら、一度表情を変えると元に戻れません。
なので、そのための矢印を引きます。
先ほどの灰色のStateで右クリックして、Make Transitionします。
今度は、これを一番右の赤いExitに持っていきます。
Exitに行くとコマはゴールし、またEntryから入ってきます。
そして、勝手にスタート地点のオレンジNew Stateに行くわけですね。
遷移の条件は、Scanner NotEqual 1 としました。
パラメータが1ではなくなったとき、スタート地点に帰ります。
Has Exit Timeも忘れずに外しておきます。
ちなみに、左上の水色(?)のAny Stateというものがあります。
ここから遷移を引いた場合、どのマスからでも条件を満たせば移動できます。
表情と表情の間にタイムラグなく(真顔を挟まずに)滑らかに変化させる場合などに使います。
ExpressionsMenuで制御する以上、操作のタイムラグは絶対に発生するので
これが主に有効になるのはジェスチャーによる制御の場合だと思います。
あとは、今回の例にさらにもう一つState(眼鏡)を追加した場合、
Any StateからScanner Equal 0 で矢印を引っ張ればもとに戻る遷移を一本化できますね。
これが、Animation Controllerの仕組みです。
同じレイヤーのAnimationは1つしか再生できない、というのも何となく分かってもらえたかと思います。
コマは1つしかないので、2つ以上のStateは同時にいられないわけです。
StateにAnimationを挿す
次に、作成したStateに再生したいAnimationを挿します。
Stateの移動自体は設定しましたが、実はこのままだと空のままですね。
設定をしないと何も再生されません。
先ほどの灰色のStateを選択し、Motionに再生したいAnimationをドラッグ&ドロップします。
最初に述べましたがAnimationは作ってあるものとします。
一晩寝かせたものがこちらです
他の設定はともかく、Write Defaultsがオンになっているのを確認しましょう。
これがオンになっていると、そのマスから出ていったとき変化していた値を元に戻します。
逆にオフだと、このマスを出て行ってもゴーグルが残ったままになります。
New State(スタート地点)の側に明示的に「オフにしろ」というAnimationも置けますが
そんなことをするくらいなら普通はチェック一つ入れた方が楽だと思います
ここまでで、
「Scannerが1になったらゴーグルを表示するマスに移動する」
「Scannerが1ではなくなったら値を元に戻してゴーグルを消し、スタートに戻る」
という設定が完了しました。
Expression Menuにスイッチを作る
最後に、Expression Menuに設定をしていきます。
新しく作るなら Create > VRChat > Avatars > Expressions Menuです。
ところでどうもExpressionにsがついたりつかなかったりします。
やめてほしいなそういう表記ゆれ。
ここまで、遷移の条件と動きを設定しました。
ですが、肝心の、変数の値を変える手段が今のところありません。
これをExpression Menuから変化させるわけです。
下のAdd Controlから新しいスイッチを作成します。
スイッチに表示される任意の名前と、設定するParameterと値を設定します。
今回は、Int型のScannerを1にする、という設定をします。
Typeは今から説明しますが、Toggleにします。
ちなみに、VRC Avatar Descriptorの側で各ファイルを先に挿しておかないと
この段階で変数の一覧が正しく表示されません。
新しく作るなどで未設定の場合は前の節の画像を参考に挿してきましょう
これで、オンにしている間Scannerを1にするというスイッチができました。
ところで、このTypeについての説明を少しだけします。
Button
Buttonは指定された変数を一瞬(約1秒)だけ指定の値にします。
その後は元の値に戻ります。
今回の設定だと、Scannerの値が戻るとゴーグルが消えてしまうので不適です。
これが有効なのは、弾を撃つなどの単発で完結するAnimationです。
オンオフする必要がなく、遷移が間に合う限り連射できるのが特徴です。
Toggle
Toggleは選択するとオンオフが切り替わり、オンの間指定の値になります。
大正義です。
だいたいこれでうまくいきます。
オンになっている間、リサイクルマークみたいなのが浮かびます。
描写が下手ですが見てみるとわかります
Two Axis / Four Axis / Radial Puppet
Puppet方式は選択するとポップアップが開きます。
スティックの位置に合わせてFloat型の値が少しずつ変化します。
Float型の値を用意し、Controllerにも特殊なStateを作る必要があります。
そのため、今回は見なかったことにします。
使いこなせば笑顔と悲しみが混ざるような複雑な感情表現や、
武器の伸縮と角度を同時設定するなどの芸当ができます。
ともあれ、基本はToggleが大正義です。
間に合わない高度な設定がしたくなるまでIntとToggleでたいがい何とかなるはずです
ちなみに、定義済みParametersのGestureLeftなどを使う場合
行動に応じて勝手に値が発生するのでもちろんこの設定は不要です
VRChatで確認する
ここまでで、こんな設定をしました。
「Expression Parametersに設定した変数を」
「Expression Menuで値を切り替え」
「それに基づいてController上のStateを移動し」
「Stateに設定されたAnimationが再生される」
これで道筋はできたはずなので、VRChat上で確認します。
アバターをアップロードするか、Build & Testします。
2019から爆速になりましたね。
操作してみて、思った通りの挙動をすれば成功です。
お疲れ様でした。
上手く動かない場合
Q. 全く動かない
A. ParametersとControllerでスペルミスしてない?
Weightちゃんと1にした?
Transition繋がってる?遷移条件合ってる?
正しいAnimationをStateに挿してる?
Expression Menuの値の指定合ってる?
そもそも正しいファイルをAvatar Descriptorに挿してる?
Q. 一瞬表示された後消える
Has Exit Time外した?
元に戻るためのTransitionの遷移条件合ってる?
あとはAnimation固有の問題(アイテム出し入れのフレームは1つだけにするなど)
絶対あってると思ってもしょうもないミスをします。にんげんだもの みつを
嵌るとどうしようもなくなるので寝て翌日に再確認する、
VRChatのストレス発散ワールドに行くなどの方法も有効です
あと、UnityをVRChatを同時起動してテストしている場合
再アップしたあと一回別のアバターにするなどしないと反映されないことがあります
ともあれ、うまく反映されればそれなりに達成感があります。
一回仕組みを理解すれば応用が効くのでぜひとも習得しましょう
なにか不足している情報などがあればコメントやTwitterなどで教えてください。
それでは、良いVRChatライフを。