TKSPのUnity関連ブログ

Unityに関することで書きたいことを書く.

VRChatで物を取り出すアニメーションを作成する[VRChatアバター改変のすすめ その2]

はじめに

こちらの記事は前回の続きです。
tksp-unityroom.hatenablog.com

前回、キャラクターを動かすアニメーションの設定ができたので今度は物を取り出す機能の作成を行いたいと思います。

物を取り出す

物を取り出すためには、アバターと同じ位置に物を出現させる必要があります。
そのため、物を取り出す前に、物をアバターに追従させる技術を知っておく必要があります。

物を追従させる

方法は2種類あります。
応用の幅が広いので、ぜひ2の方法は知っていてほしいです。
応用をしない場合は1の方法が処理が軽いので、使い分けられるようになっていただけたら嬉しいです。

  1. 物体をボーンの中に入れる
  2. Constraint特性で結合する

最初にCubeをHierarchy内で作成し、InspectorのSize(XYZ全部)を0.1にして大きさを調整します。
f:id:ymtkyorosiku:20211003142625p:plain

Cubeにはデフォルトで4つの特性(コンポーネント)がついていますね。Transformeについては前回説明したのでそれ以外についてザックリ説明します。

Mesh Filter

その物体の形を確定させるもの

Mesh Renderer

Mesh Filter で指定された形で絵を描いて欲しいとコンピュータに命令を送るもの

box Collider

Collider同士でぶつかると反発する当たり判定の特性。

不要なコンポーネントを外す方法

今回、BoxColliderがついたままだとVRChatのアバターに自動的に付与される当たり判定と干渉して不具合が起きるのでBoxColliderを外しておきます。
消したいコンポーネントを右クリックして、Remove Component で外せます。
f:id:ymtkyorosiku:20211003143458p:plain

ボーンとMesh Rendererの関係

さて、ボーンとは何ぞやといいますと骨です。(意味不)
大体のアバターがArmatureの中に入っている構造になっているかと思います。(Armatureが無ければ別の名前で同じような構造になっているかと思います。)
f:id:ymtkyorosiku:20211003144434p:plain

キャラクターの構造としては、先ほど説明したMesh Rendererでその形を描くように命令されているのですが、それだとポーズが取れないです。
そのため、ネロちゃんはbodyにSkinned Mesh Renderer という別の特性を持っています。
f:id:ymtkyorosiku:20211003164451j:plain
これは、Meshの中に入っている形を対応されたボーンのTransformの値で変形させてから描くように命令するMesh Rendererです。
例えば、Arm(腕)ボーンのTransformを変更するとSkinned Mesh Rendererが表示する形が変形することが確認できます。

f:id:ymtkyorosiku:20211003153602g:plain

添付画像のように、Transformの変形はInspectorからの直接指定だけではなく、Hierarchyで物体を選択した後、Sceneでドラッグ操作することでも変更可能です。
変形の方法は以下の通りです。
f:id:ymtkyorosiku:20211003153428p:plain

  1. 位置(Position)
  2. 回転(Rotation)
  3. 大きさ(Scale)
  4. 上記全部まとめてできる

編集をする際は、細かい部分はこちらで調整し、最後は直接指定で小数部分をきれいにしたりすると良いかと思います。

方法1: ボーンの中にCubeを入れる

ボーンの中にCubeを入れて、ボーンを変形させると、追従することが確認できます。
今回はこちらの方法は使用しません。
f:id:ymtkyorosiku:20211003185130p:plain

方法2: Constraint特性で結合する

Constraintは簡単に言えば磁石のようなものだと思っていただければよいです。

CubeにParent Constraintの特性を追加します。

f:id:ymtkyorosiku:20211003154904p:plain
Cubeに追加

Sourcesにくっつけたい物体を指定し、(今回はArmのボーン)
Is Active にチェックを入れて有効化します。
f:id:ymtkyorosiku:20211003160036p:plain

実はこの状態でHierarchyのボーンを動かしてもConstraintが動いているのかは確認できません。
確認するためにはゲームを起動させる必要があります。
ゲームを起動するのは上の再生ボタンです。

f:id:ymtkyorosiku:20211003160423p:plain

  1. ゲーム開始、停止
  2. 一時停止
  3. 一時停止中、1frameずつ進める

f:id:ymtkyorosiku:20211003163020g:plain
ゲーム中に毎frame磁石の力が働くので、Cubeがくっついていることが確認できます。
しかし、Scaleは追従してませんね。
それは、Parent ConstraintがPositionとRotationに追従させる特性だからです。
Scaleも追従させたい場合は、Scale Constraintも追加しましょう。
(今回は追加しない)
f:id:ymtkyorosiku:20211003185531p:plain

この時点でお気づきかと思いますが、全部追従してしまう①の方法に対して、追従する箇所を選べる②の方法は圧倒的に応用性が高いです。

Constraintはいくつか種類があります。Parent Constraint はPosition Constraint と Rotation Constraintを一つにまとめて動作を軽くした特性になります。
f:id:ymtkyorosiku:20211003161127p:plain

さて、最後にアバターの中にCubeを入れておきましょう。VRChatにアップロードするデータは VRC Avatar Descriptor 特性を持つ物体だからです。
データが無ければ存在しないのと同じですからね。

f:id:ymtkyorosiku:20211003161718p:plain

この状態でアップロードするとCubeが追従しているのが確認できます。
f:id:ymtkyorosiku:20211003162528p:plain
今は腕に追従しているので、くっつけるボーンをHandに変更し、Cubeの座標も手の位置にしておきましょうか。
これで手に持っているように見えるはずです。
f:id:ymtkyorosiku:20211003162611p:plain
鏡なので反転するよー
f:id:ymtkyorosiku:20211003162938p:plain

アニメーションを作成する

さて、いよいよアニメーションを作成していきますが、アニメーションって何なのでしょうか?
覚えていただきたいのが、Unityのアニメーションは、「物体の特性に値を上書きする」ものだということです。

前回のアニメーションでキャラクターに拍手をさせたと思うのですが、あれはボーンのTransform属性の座標と回転を変更することによって表現されています。
つまり、Inspectorの値を書き換えることがアニメーションの本質なのです!
では、実際にアニメーションを作成していきます。
cube_off,cube_onのアニメーションと、例としてnero_FXLayerというアニメーションコントローラを作成します。(前はVRCSDKからActionLayerをコピーしてきましたが、FXLayerのサンプルはないので新規作成です)
f:id:ymtkyorosiku:20211003163831p:plain
f:id:ymtkyorosiku:20211003163843p:plain
f:id:ymtkyorosiku:20211003164110p:plain

作成したFXLayerを選択した状態でAnimatorタブを開きます。
LayersにCubeLayerを追加し、歯車のアイコンからwaightを1にします。
cube_off,cube_onの順にドラッグ&ドロップします。(オレンジの矢印がOffに行くようにしたい)
f:id:ymtkyorosiku:20211003170606g:plain
f:id:ymtkyorosiku:20211003170823j:plain

ちなみにオレンジの矢印はEntryで右クリックをして引き直す項目があるので、そちらでOffに行くように設定できればいいです。
f:id:ymtkyorosiku:20211003165801p:plain

これが、前回解説していなかったもう一つのStateを増やす方法です。
では、アニメーションに特性を変化させるKeyを打っていきます。
Action Controller をアバターのAnimator Compornent内のControllerに指定します。
f:id:ymtkyorosiku:20211003170301p:plain
Animationタブを開きます。

InspectorでAnimator Compornentを所持している物体を選択すると、AnimatorタブとAnimationタブがそれぞれ、Animator CompornentのControllerに指定されているAnimationControllerに紐づけされます。

画像で説明すると、1を選択状態にすることで、2に設定しているControllerを3,4で編集することが可能になります。
f:id:ymtkyorosiku:20211003171652p:plain

キーを打つ

方法は簡単です。Animationで編集したい項目を選択してから録画を開始し、Inspectorの値を変更するだけです。

f:id:ymtkyorosiku:20211003173214p:plain
f:id:ymtkyorosiku:20211003173432p:plain

  1. 編集したいアニメーションを選択(編集対象がnero_0.0.0、編集先のControllerがFXLayerになっているのでFXLayerの全Stateに設定されているアニメーションが一覧で表示される)
  2. Key録画開始
  3. アニメーションで操作する物体選択
  4. ActiveをOffにする
  5. CubeのActiveをOffにするKeyが生成される
  6. Key録画終了

ちなみに、④のActiveについてですが、こちらをOffにすると「自身のTransform以外のすべての特性を無効化し、自身の階層下オブジェクトのTransform以外のすべての特性を無効化」する効果があります。
つまり、MeshRendererが無効化されるのでコンピューターにMeshの形を描く命令が飛ばなくなります。
結果、Cubeが描かれないため表示されないのです。ConstraintはActiveになったときに手の座標までワープする感じになりますね。
ワープするのが一瞬見えてしまうのが嫌だという方は、Mesh RendererのActiveを切る方法でアニメーションを作成しても大丈夫です。
しかし、物体自体のActiveを切ってしまったほうが、表示していないときの処理が軽くなるのでお勧めです。

そしたらOnのアニメーションを作成しましょう。
上記と同じ方法でKeyを設定する方法でもよいのですが、OffのKeyを選択(青色になる)して、ctrl+c(コピー)して編集対象をOnのアニメーションに変更し、1frame目にctrl+v(ペースト)してActiveをonにする方が楽です。
f:id:ymtkyorosiku:20211003180018g:plain

アニメーションコントローラーの設定(前回解説したのでわかるはず。boolは0か1のフラグでしたね)

f:id:ymtkyorosiku:20211003180715p:plain

  1. Parametersタブにフラグをboolで追加
  2. フラグ名はなんでもよいが、とりあえずCubeにする
  3. MakeTransitionで結ぶ
  4. MakeTransitionで結ぶ
  5. off -> onの矢印を選択
  6. Has Exit Time無し
  7. フラグをtrueで追加
  8. on -> off の矢印選択
  9. Has Exit Time無し
  10. フラグをfalseで追加
  11. offのStateを選択
  12. Write Defaultsをoffにする
  13. onのStateを選択
  14. Write Defaultsをoffにする
Write Defaultsについて

現在のバージョンではVRChat公式が非推奨と言っているのでoffにしましょう。Write Defaultsがどういうものか知りたい方は調べてみてください。

動作確認

キャラのAnimator特性にControllerが設定されている場合、Animatorタブのコントローラーは紐づいているので、Gameを開始することで実際のアニメーション遷移を確認することができます。
Gameを開始し、Parametersの値を変化させることでアニメーションの遷移が行われて、Cubeの表示がOn,Offされていることが確認できます。

f:id:ymtkyorosiku:20211003183058g:plain

アニメーションコントローラーを外す

編集が終わったのでAnimatorのControllerはNoneにしましょう。右側のボタンで直接指定できるのでNoneを選択します。
f:id:ymtkyorosiku:20211003181809p:plain

次は、VRChatからアニメーション操作をするための処理を追加します。
動作確認が正しく動いていた場合、ここが間違っているか、アップロードのデータに含まれていない(キャラの中にCubeを入れていない)ことが多いので確認してください。

Parameterの追加

Addから追加
f:id:ymtkyorosiku:20211003181445p:plain

Menuの追加

On,Offを制御したいのでToggleを追加
f:id:ymtkyorosiku:20211003181522p:plain

アップロード

完成です!
Cubeを取り出すことができました!
f:id:ymtkyorosiku:20211003192537g:plain

取り出すものを好きな物体に変更する

Cubeの代わりに好きなオブジェクトで同じ方法を試してみるのもよし、Cubeの中に好きなものを追加して、CubeのTransform以外の特性を削除するのもよし

ActionLayerのアニメーションを見てみる

ここまでの説明でアニメーションで何をやっているかが分かったはずなので、怖くないですね。
ControllerにActionLayerを設定して、拍手のアニメーションを見てみましょう。
f:id:ymtkyorosiku:20211003183900p:plain
Animatorコンポーネントの値を書き換えてるだけでした。全部ボーンに関するパラメータですね。

Animator特性について

自分もあまり詳しくないので、なんとなくの雰囲気ですが以下のような感じです。
(Humanoidとは何ぞやとかになるので、詳しく知りたい方はこちらを参照
Unity Humanoid Avatarの解説 [VirtualCast]
)
1.Game中、ControllerのアニメーションをAvaterに適用する。
2.Game中、Avatar(大抵はFBXファイル)の設定を使用してアニメーションに存在する設定値でTransformの値を上書きする。

最後に

お疲れ様でした。
ただCubeを表示するだけなのに教えておきたいことが多すぎて意外と大変でした。

次は色を変化させるアニメーションを作成できたらなと思っています。
tksp-unityroom.hatenablog.com