VRChatパブリックログ

VRChatでの体験を紹介します

最新版(10/02時点)自動まばたきの実装【VRChat技術情報】

R.I.P./レガシーアニメーション

最新版のVRChatにおいて、レガシーアニメーション(animationコンポーネント)が利用不可能になるとの告知がありました。それに伴い、以前広く使われていた「レガシーアニメーションを利用した自動まばたき」が利用不可能になります。(現状まだそうならないかも知れませんが)

言及した公式声明

旧自動まばたきの記事

ただし、公式声明でも言及されているとおり、実際には必ずしもレガシーアニメーションを使う必要は無かったため、今後自動まばたき自体が使用不可能になるわけではありません。いくつかの代替方法があります。

  1. アイトラッキングを実装し、それに付随する公式の標準スクリプトによるまばたきを利用する。
  2. animationコンポーネントの代わりにanimatorコンポーネントを利用する。
  3. Idol、そしてハンドサイン等のアニメーションオーバーライドで置き換えるアニメーションにまばたきを定義する。

必須では無いですが、アニメーションファイルのはたらきや、今回停止されたレガシーアニメーションについての詳細は、以前記事を書いたのでそちらを参照してください。ここを理解しているともしかしたら今回の記事も少し読みやすくなるかも知れません。

 

1.アイトラッキングを実装する方法

 このブログで以前に紹介した方法です。

アイトラッキング(目線のアニメーション)に伴って、まばたきも自動でするようになります。

メリット:

目が実際に動くようになる(相手を見たりそっぽを見たりとある程度ランダムに、まぶたの動きも連動した自然な挙動になる)。

設定しないとならない項目が少なく、分かってしまえば実装の手間は一番少ない。

デメリット:

まばたきの頻度を調整できない。

表情と干渉回避するためには顔のメッシュを2つ用意する必要がある。

表情との干渉回避しているとき、リップシンクも停止する。回避は煩雑だが可能。

個人的にはこの方法がおすすめです。簡単かつ圧倒的に表情豊かになります。

利用方法については上記の記事を参照してください。

表情と干渉回避する方法はanimatorを利用する方法と同様の手法を利用するため、後述します。

  

2.animatorを利用する方法

animatorコンポーネント、つまりanimationコンポーネントを利用するレガシーアニメーションを使った従来手法の直接の代替方法です。

メリット:

動作としては従来方法に最も近い。

まばたきの頻度を自由に設計できる。

デメリット:

 

特にないかも。 

3.アニメーションオーバーライドで置き換えるアニメーションにまばたきを定義する

アバターに標準実装されている、規定のanimator controllerを利用して、そこで呼び出されるアニメーションオーバーライドで指定したアニメーション全てに個別にまばたきのアニメーションを定義する方法です。この方法は以前から利用している人は居ました。

文面通り、一番泥臭い方法です。ただし、表現の自由度は一番高いです。

メリット:

表現は一番精密。表情とまばたきを組み合わせても顔のメッシュがおかしくならないように調整できる。

表情との干渉回避はアニメーションで定義するため、他の方法のように複数のメッシュを用意する必要が無い。

デメリット:

設定項目が大量にある。調整は勿論、Idleアニメーションについては表情だけで無く全身のアニメーションを定義する必要があり、作業量はダントツに多い。

以上の理由により今回の記事では解説を省略すること。

 

新自動まばたきの実装

この記事では特に「2.animatorを利用する方法」について解説します。

既に旧自動まばたきを実装しているアバターの場合、アバターのルート(一番上)にanimationコンポーネントがあると思うので、一応そのコンポーネントを削除します。(inspectorのコンポーネントの項目の右上の歯車のマークをクリックで削除の命令を呼び出せます)レガシーアニメーションが復活する可能性があるので、Ctrl+Dでアバターを複製しバックアップをとっておいて複製したアバターで作業するのもいいと思います。

Plojectタブ上で右クリックで出てくるメニューより、【Create>Animation】でアニメーションファイルを作成します。アバターのFBXが置いてあるディレクトリの下にAnimationというディレクトリを作成し、その中に置いておくと作業しやすいです。

旧自動まばたきの方法ではレガシーにチェックを入れる等の工程が挟まりましたが、アニメーションはデフォルトでレガシーではない形式なので、その点は操作する必要はありません。

Animatorコンポーネントは一つのオブジェクトに一つしか配置できず、かつアバターのルートに置いてあるAnimatorにはアップロード時に規定のAnimation Controllerが配置されるため、ここのAnimatorは利用できません。そこで、ここでは顔のメッシュが配置されているオブジェクトに直接Animatorを作成することとします。(動作さえすればどこでもかまいませんがAnimator理解していない場合は記事の通りにするのをおすすめします)

まず、先ほど作成したアニメーションファイル(下図ではMohuco2-Blinkです)をHierarcy上のまばたきのシェイプキーが入ったメッシュのマテリアル(下図ではBodyです)にD&Dします。すると、そのマテリアルにAnimatorコンポーネントとそのD&Dしたアニメーションを実行するAnimation Controller(オブジェクトの名前に従ってBodyという名前のファイル)が自動生成されます。

f:id:mekokka:20180929215810p:plain

次に、ウィンドウ上のプルダウンメニューより、Window>Animationを選択し、Animationの編集画面を出します。その状態でD&D先のBodyオブジェクトを選択し、Inspectorが表示されている状態にします。すると、Animationの編集画面に先ほどD&Dしたファイル名が表示され、アニメーションが編集可能な状態になります。

f:id:mekokka:20180929220740p:plain

その状態で、まずは0:00フレーム、初期状態のまぶたの表情を定義します。赤い●をクリックするとオブジェクトに対する変更がアニメーションのキーとして登録される状態になるので、それを利用します。メッシュのInspectorよりSkinned Mesh Rendererコンポーネント内、BlendShapesの項目(デフォルトだと折りたたまれてる事があるので見つけにくいかもしれません)の数値をいじります。(このアバターではvrc.blink_left/rightがまばたきのシェイプキーなので、その数値を0~100の間で設定します)

初期値以外の適当な数値を入れると、アニメーションのキーが追加されるのですが、ここでは初期値0を再指定したいので、適当な数値を入れた後に0を入力して初期値0をアニメーションのキーとして登録しました。ここまでの作業をした状態で上の画像のようになります。

ここでアニメーション設定画面のタイムラインのシークバー(赤い縦線)を0:00にあわせて、一番上のひし形◆をクリックし、同時間のキーを全て選択した状態にします。その状態でCtrl+Cを押すと、クリップボードに0:00のキーがコピーされた状態になります。

まばたきをさせたいタイミングまでシークバーを移動させて、Ctrl+Vで0:00の初期状態(目を開いてる状態)のシェイプキーを登録します。このとき、0:00の(:)以下の数値はフレーム数であって10進法の小数の意味ではない事に気を付けてください。0:00は0秒00フレーム、1:30なら1秒と30フレームです。60FPSのアニメーションなら1.5秒時点の意味です。

ここで必ず目を開いているキーを登録してください。ここにいきなり目を閉じるキーを登録すると、0:00時点からゆっくり目を閉じるアニメーションになってしまいます。

そして更にはまばたきが終了する(再び目を開く)タイミングに同様にシークバーを移動させて、同様に目を開いているキーを登録します。この時点で目を開いているアニメーションキーが3つ登録されてる状態になります。

そして、ペーストした二つのキーの中間にシークバーを移動させて、メッシュのInspectorよりまばたきのシェイプキーをそれぞれ100と設定します。すると●を押したときの機能により、目を閉じるアニメーションキーが生成されます。

最後に、アニメーションの全長にしたい時間までシークバーを動かし、目を開いているアニメーションキーをペーストします。

これで基本的なまばたきのアニメーションは完成です。再生ボタン▶を押して動作を確認してください。(上の説明通り全長7秒のアニメーションとして作成したまばたきのアニメーションが下図)

f:id:mekokka:20180930174047p:plain

まばたきのパターンを複雑にしたい場合は同じ要領でアニメーションに複数回のまばたきを定義して、アニメーションを長いものにすればいいです。

f:id:mekokka:20180930010846p:plain

最後にProjectタブでアニメーションファイルを選択してInspectorを開いてLoop Timeにチェックを入れます。これでアニメーションが永久ループするようになります。

あとはアップロードするだけで動作します。

アバターの構造によってはアイトラッキングとアイトラッキングによるまばたきが動作してしまう場合があるので、切りたい場合はメッシュの名前をBodyからその他の適当な名前に書き換えます。

 レガシーアニメーションでまばたきを作っていた場合に流用する場合は、レガシーアニメーションのチェックを外して通常のアニメーションに設定し直す必要があること、アニメーションファイルをアバターのルート(一番上)から顔のメッシュのanimatorへ配置し直したときにアニメーション設定画面でオブジェクトのアドレスの項目が黄色(missing)になっているので、そこを二回クリック(ダブルクリックではない)にして、そこに入力されている文字列を空白(全削除)する必要があること注意して下さい。

まばたきと表情のシェイプキーの干渉回避

方法は二つあります。

  1. 今まで通りアニメーションからanimatorの動作を停止させる方法
  2. 二枚のメッシュを使い分ける方法(アイトラッキングはこっち)

アニメーションからanimatorの動作を停止させる方法

イメージとしてはレガシーアニメーションを利用していた時と同様に、まばたきのアニメーションの動作を別のアニメーションから動作停止させる方法です。

ただし、animationコンポーネントとは異なりanimatorコンポーネントを制御するためのアニメーションキーの作成は通常エディタ機能では作成できません。(?)そこでどうしようもないと考えていたのですが、

VRChatの海外コミュニティで公開されていたanimator版アイテムのトグルスイッチで利用されているアニメーションでanimatorコンポーネントの動作を停止させるアニメーションキーを利用しているのを見て転用することにしました。

animatorの動作を停止/再生させるアニメーションキーのみが入ったアニメーションファイルをこちらで配布しているので、まずこれをダウンロードしてください。

f:id:mekokka:20181002144430p:plain

ダウンロードしてインポートしたアニメーションファイルを選択し、アニメーション編集画面で確認するとこのようになっています。Behaviour.EnabledがAnimatorの動作を制御するアニメーションキーです。

0:00フレームの一番上のキー◆をクリックし、Ctrl+Cでコピーします。

以前までアニメーションオーバーライドで追加したアニメーションに自動まばたきの停止を組み込んでいた人は、animationコンポーネントの停止のアニメーションキーとこのアニメーションキーを置き換えましょう。

f:id:mekokka:20181002145848p:plain

具体的には、まばたきと干渉してしまうアニメーションのファイルを選択して、アニメーション編集画面を開き、0:00フレームを選んでこのようにペーストします。

配布したファイルの初期値では、Behaviour.Enabledの値が1で、これはanimatorコンポーネントを再生させるという意味なので、停止させる場合は1の数字の部分をクリックして0に書き換えます。これによって表情のアニメーションが動作している間はまばたきのアニメーションが停止するようになります。

逆に、まばたきを動作させたい表情の場合は、この値を1にしてください。

顔のメッシュ、およびanimatorコンポーネントが入っているオブジェクトがBodyではない場合は、ここの表示が黄色になっている場合があります。黄色になっていない場合でも、まばたきのanimatorコンポーネントが入っているオブジェクトがBodyという名前じゃ無かったり、オブジェクト配置が違う場合はさらに編集する必要があります。

・BodyではなくFaceという名前の場合

Bodyと書いてある部分を二回クリック(ダブルクリックではない)するとここの文字を編集できるようになるので、

Face

と書き換える。

・Bodyがアーマチュア等、別のGameObjectの中に格納されている場合

Bodyオブジェクトが、

Object1

 ┗Object2

   ┗Body

と言うように別のオブジェクトに格納されている場合は

Bodyと書かれている部分を二回クリックして、

Object1/Object2/Body

と書き換えます。

以上の操作で動作するようになります。(表示が黄色でなくなったら成功)

表情のアニメーション自体の作成方法は下記のブログを参考にしてください。

2枚のメッシュを使い分ける方法(アイトラッキングはこっち)

Animationコンポーネントを利用する方法は上記の方法で基本的には良いのですが、それでも局所的に不都合がある場合と、アイトラッキングを利用している場合の解決には2枚のメッシュを使い分ける方法があります。

方法としては大まかに二つあります。

メッシュのオブジェクトを複製してまばたきアニメーション用のメッシュと表情用のメッシュを分け、

  1. オブジェクトのオンオフで切り替える方法
  2. オブジェクトは両方ONで、シェーダーのCutOffで片方を非表示にする方法

です。

1.の方法では、Unity上の作業だけで簡単に実装自体はできたのですが、一瞬メッシュが重なって表示されるか、両方のメッシュが非表示の状態になるかのどちらかが起こり、アニメーションのキーのタイミングを調整したり、アニメーションの補間方法(Free/Flat/Constant)を調整してもなぜか解消できなかったため、この方法は没になりました。

対して2.の方法は、上記の問題は発生しなかった上に、単純にそれぞれのメッシュの表示非表示のトグルとしても、顔の一部分だけの表示としても利用できるため、口パク部分だけまばたき用メッシュを利用し、目は表情用のメッシュを利用ということもできます。今回はこちらを紹介します。

テクスチャにアルファチャンネルを追加する

まず、顔のメッシュ用のテクスチャに少し手を加えます。もちろん、元々のテクスチャファイルはバックアップを取っておいてください。今回は簡単にメッシュの表示非表示だけさせたいため、GIMP等画像編集アプリで画像にアルファチャンネルを追加し、画像全体のアルファ値を適当な値にしてください。GIMPなら不透明度を0~99の適当な値にします。ペイント作業などは必要ありません、全体に透過情報を追加するだけです。シェーダーのCutOffはアルファ値が設定値以下の部分を完全な透明にするため、残りはUnity上の設定で調整できます。編集アプリ上では透過したとき色が薄く表示されたりしますが、これは透過の表現であって、色そのものの情報は書き換わっていないので非透過部分に関しては編集以前と見え方は変わりません。

f:id:mekokka:20180930191119p:plain

非表示用のマテリアルを作成、割り当てする

Unity上の設定に戻ります。

まず、顔のメッシュのオブジェクトをCtrl+Dで複製します。例えばBodyというオブジェクトだった場合、Body (1)等の名前で複製されるので、今回はわかりやすくBody-expressionとリネームしました。この状態だと格納されているまばたき用のAnimatorコンポーネントもコピーされているので、表情用のメッシュのオブジェクトの方の物はAnimatorコンポーネントを削除します。

f:id:mekokka:20180930191625p:plain

次にメッシュ非表示用のマテリアルを作成します。顔のメッシュに使っているマテリアルをCtrl+Dで複製してください。今回はFaceから複製したマテリアルを、Faceoffという名前にしました。

作成した非表示用マテリアル(Faceoff)の設定を変更します。Main Textureに先ほど作成したアルファチャンネルつきのテクスチャファイルを設定します。Renderring ModeをOpaqueからCutoutに変更してください。シェーダーによってはRenderringModeの項目が無い代わりに個別にシェーダーを分けている場合もあるのでその場合はシェーダーを切り替えてください。

Inspectorタブ下部のマテリアルプレビューを確認しながら、Alpha Cutの値を調整して透過するようにしてください。透過状態になるとマテリアルプレビューから球体の表示が消えます。

f:id:mekokka:20180930193453p:plain

このままだと、表示用のマテリアルと非表示用のマテリアルで別々のテクスチャファイルを参照しているので、その点において容量が2倍になっています。このままでも使えますが、軽量化を気にする場合は表示用のマテリアルのMain textureも先ほど作成したテクスチャファイルにして統一してください。

f:id:mekokka:20180930193638p:plain

現状では、BodyのメッシュとBody-expressionのメッシュが両方表示状態で重なっているので、まばたきしたときにちらついたり表示が2重になってしまいます。そこで、表情用のメッシュのほうには先ほど作成した非表示用のメッシュ(Faceoff)を適用します。上図のようにHierarchy上の表情用メッシュ(Body-expression)へD&Dします。これで初期状態ではまばたき用のメッシュは表示され、表情用のメッシュは非表示の状態になります。

表情用のアニメーションの設定

基本的な表情のアニメーションの作り方についてはこちらの記事を参照してください。

今回の場合も通常通り表情のシェイプキーを割り当てた2フレームのアニメーションを作成するのですが、このときアニメーションで操作するのは表情用のメッシュの方になるようにしてください。まばたき用のメッシュはまばたきのアニメーション、および設定している場合は口パクでのみ動作するようにします。

そのアニメーションにメッシュの表示非表示の切り替えも追加します。

先ほどのアニメーションの編集時と同じようにアニメーション編集画面の●ボタンを押してオブジェクトの変更内容がアニメーションのキーとして登録される状態にします。

0:00フレームにシークバーを合わせた状態にして、まばたき用のマテリアル(Body)に非表示用マテリアル(Faceoff)、表情用のマテリアル(Body-expression)に表示用のマテリアルを割り当てます。するとそれぞれの操作が0:00フレームにアニメーションのキーとして登録されて、表情を呼び出したときに瞬時にメッシュが切り替わるようになります。

再生ボタン▶を押して動作を確認してください。メッシュの切り替えはアニメーションキー単体で動作する(というか単体で2つのキーとして動作する?)ので、シェイプキーのように2フレーム分用意する必要は必ずしもありません。

f:id:mekokka:20180930200825p:plain

以上で完成です。

テクスチャを2枚用意(目周辺だけ表示/それ以外を表示)してCutoutによる切り抜きを複雑にすれば、目と干渉しない/口と干渉しない表情についてはまばたき用のメッシュのシェイプキーを動作させて表示し、干渉する部分については表情用のメッシュを表示する等のこともできます。これはシェーダーを簡単に書き換えればテクスチャ1枚(目周辺だけ表示)で対応することもできます。例としてCubed PaladoxのCutoutレンダリングモードにおいて、テクスチャのアルファチャンネルの働きを反転させたシェーダーをこちらに配布します。MITライセンスなので自己責任で利用してください。

メッシュを2枚利用するのでその点においてポリゴン数が二倍になるので、ポリゴン数制限としては厳しい面もあります。アニメーションでポリゴン数をごまかす事もできますがグリッチまがいの方法なので推奨はしません。