見出し画像

Avatars 3.0 を超える力

この記事はVRChatで特殊なアバターを作る際に使ったHack等の紹介です。
ある程度のUnityの知識があって、凝ったことをしてみたいという人向けです。

前置き

VRChatで Avatars 3.0 がついにリリースされました。仕組みや実装が大きく変わって困っている人もいるようですが、自分のような 特殊なアバター 勢にとっては、(比較的)シンプルな方法でできることが大きく広がっており、とても良い更新だったと思います。

さて、既存のアバターをAvatars 3.0に移行するエディタ拡張が続々と作られているのですが、 Avatars 3.0で作られたものを装飾・拡張するツールを作るのは困難 だという問題に突き当たりました。何かしらの操作特性を変えるにはアニメーターコントローラーを変えねばならず、それには無限のパターンがあるようになったためです。

前置きが長くなってしまいましたが、 すぐツールには出来ないけど、もしかしたら役に立つかもしれないHack を紹介していきます。これらは 2020/08/09 に確認できたもので、VRChat, VRChatSDK, UnityEditorのバージョンアップによって変わる可能性があります。
上の方には普通の話、下の方には異常な話が書いてあります。

AnimationParameterの使いみち

Avatars 3.0でAnimatorControllerがカスタマイズできるようになり、独自のAnimationParamaterを追加して使えるようになりました。最も一般的な使い方は、AnimatorStateへの遷移条件に使うことでしょう。この記事は一般的ではないので、もう少しマイナーな使い方を2つ紹介します。(Hackではないです)

1つ目は、AnimatorStateのParameterとして使うことです。AnimatorStateの `Parameter` チェックボックスにチェックを入れることで、再生の仕方を変えることが出来ます。
SpeedのMultiplierは再生速度を変更できます。羽根のアニメーション速度を変えるのに使いました。
NormalizedTimeをオンにすると、アニメーションが自動で進むのではなく指定時刻の値をサンプリングするように変更出来ます。例えば、色を青から赤に変化させるアニメーションを作り、ExpressionのRadialPuppetをそれに指定すると、ActionMenuから色を変えられ、それを固定することが出来ます。拡張性の高いブレンドシェイプみたいな使い方ですね。
(MirrorとCycleOffsetはあんまり変更しないんじゃないかな)

画像1

2つ目は、BlendTreeに使うことです。BlendTreeのできることは多いので解説はしませんが、動きのあるアニメーションの割合を連続的に変えるときなどに便利です。↓では足をぷらぷらさせるアニメーションとそれを止めたアニメーションを混ぜることで、足ぷらの大きさを変更しています。長さもブレンドされるので、アニメーションの長さは揃えたほうが制御がしやすいです。

画像2

Constraintによるなめらかな補完

Constraintは指定した位置や回転にピッタリと合わせる機能のコンポーネントですが、Sourcesに自身を足すことで徐々にその値に近づけるような挙動にすることが出来ます。2点間の繋ぎ変え等にはSources.Weightをアニメーションさせた方が良いと思いますが、軽量な緩衝材としてやサンプリングされる値への追従に使えると思います。
ただし、フレーム単位で動くのでFPSに依存することと、指数関数的に動くので物理的に自然ではないことに注意です。
(↓ActionMenuで設定したArmaturePositionに毎フレーム1/5ずつ近づける)

画像3

DebugInspector

インスペクタータブの右上の `三` みたいなやつのメニューから Debug を選ぶことで、エディタ拡張を無効化し、シリアライズされている値を直接編集することが出来ます。いろいろ悪いことが出来てしまうのですが、今回は AvatarMaskにTransformを後から追加する のに使いました。(ファイルを直接編集しても出来ます) Gestureレイヤーにアクセサリーを動かすアニメーション等を追加する場合などにどうぞ。

画像4

SkinnedMeshRendererのboneを変更する

SkinnedMeshRendererは、ボーンに合わせてメッシュを描画するコンポーネントです。どのボーンを参照するかはDebugInspectorからでも見ることは出来ませんが、この値はスクリプトから `SkinnedMeshRenderer.bones` として読み書きができ、SkinnedMeshRendererにシリアライズされているため、アップロードしたアバターにも反映されます。(実際にどう入ってるのかは不明)

BoolのBlend

状態AのときはAをTrueにしてBをfalseに、状態BのときはBをTrueにしてAをFalseにする、というアニメーションを作ることは多いと思うのですが、実はこの2つがブレンドされると、AもBも両方Onになっている瞬間が存在してしまいます。これは、アニメーションの内部値としてはチェックボックス(bool)のTrueが1、Falseが0となっており、そのブレンドされた値(例えば0.5)もTrueと判定されてしまうからです。Trueと判定される条件は > 0.001 なので、ちょうど真ん中で切り替えたいときはboolの値を 0.002、 完全に切り替わってから有効にしたい場合は 0.0011 のように設定するといいでしょう。
アニメーターを持つGameObjectではなく、アニメーションクリップファイル自体を選択することにより数値をAnimationウィンドウで直接変更できる状態になります。

画像7

AnimatorのBindを奪い取る

AnimatorはGameObject名を参照して動かしているので、(HumanoidBoneであっても)同名のGameObjectを同じ階層かつ若い位置に用意することで、それを操作するように変更できます。基本的には役に立たないのですが、 Armatureのルートを他の方法で変更できるようにする のは使いみちがあるかもしれません。 (他の部分のBindも奪い取ることは出来ますが、それはAnimationのキーやVRCAnimatorTrackingControlで調整しましょう)
浮遊アバター設定機能GravityBreaker で使っているのに加え、 デスクトップ用浮遊設定 でも有用でした。 (浮遊アバターに命かけ過ぎでは?)

画像6

ViewPositionを動的に書き換える

視点やネームプレート位置に使われるViewPositionですが、ネームプレート位置は初期値が使われるのに対し、キャリブレーションの特性はキャリブレーション時の値を参照しているようです。TPoseのアニメーターにViewPositionを変更するキーを入れることで、動的にキャリブレーション特性を変えることが出来ます。
(かつてはこれでネームプレートの位置を変更していたのですが、VRChatのアップデートによって現在の視点位置に追従するように変更されました。いい変更だと思います)

画像5


この記事が気に入ったらサポートをしてみませんか?