LoginSignup
17
21

More than 3 years have passed since last update.

VRM データをもっと Unity らしく作る

Last updated at Posted at 2020-02-25

このページ書いてあるワークフローを実現するためのツールは以下のページからダウンロードできます。

VRM を作っていると、なんだかどうにもうまくいかない、妙に手間がかかる、その原因は Fbx へのリンクが切れている点に集約されるのだろうなと思っています。

作り捨てのシーンを作るのではなく、もっと Unity らしく、工程の後戻りが可能・メンテナンス可能な VRM 用のシーン作りをして、気軽に開発と運用が出来るようにしたい訳です。

※ モデルのブラッシュアップと、ラフモデルをもとにした VRM 作成(とそれ以降の工程)を同時並行で進めておきたい、という場合だってありますよね。

もくじ

はじめに

アバター向けのファイルフォーマットである VRM を公式サイトのチュートリアルに沿って作ると、Fbx 内のメッシュへの参照が切れた状態の Unity シーンが出来上がります。

作り捨てのワークフローなので、些細な更新であっても再度 VRM を作り直す必要があり、その VRM を作るという作業が思いのほか複雑で、作成する度に思い出す・調べる必要があるかと思います。

--

例えば単発のイベント用に専用のフェイシャルを追加しよう、となった場合。

作り捨てではない、普段通りのシーン作りをしておけば、Fbx ファイルにブレンドシェイプを追加して更新すれば Unity 上のメッシュも更新されるので、なんの苦労もありません。

メッシュの増減も追跡してくれるので、アクセサリの追加や衣装替えなども Fbx を差し替えるだけで終わります。揺れ物の設定やコリジョンも使いまわせるところは使い回し、変更部分だけを更新して VRM として書き出しをすれば良いわけです。

※ セットアップ済みの VRM にブレンドシェイプを追加

ここでは、更新のたびに VRM オーサリングを1からやり直すのでは無く、Fbx への参照を維持したまま VRM に書き出すことができる Unity シーンの構築方法の一つをご紹介します。

使用している各ソフトウェアのバージョンは以下の通りです。

  • Unity 2019.2.9f1
  • UniVRM v0.53.0

VRM用のコンポーネントの収集

まずは Fbx モデルを Humanoid として読み込み、モデルインポーターの設定の Rig > Avatar Definition > Configure... で Jaw や Eye(目線がブレンドシェイプの場合)に間違ったボーンがアサインされていないかを確認します。

その後、モデルを VRM > Export Humanoid から .vrm ファイルとして書き出し、書き出したファイルを Unity にインポートします。

--

ここまでは公式のワークフローと同じで、目的は VRM Meta コンポーネントや Blend Shape の定義ファイルを作ることです。

※ A ポーズのユニティちゃん Fbx を VRM として書き出したところ

.vrm インポートが終わると、上図のように VRM コンポーネントを含んだプレハブが自動生成されます。

このプレハブに含まれる、VrmAvatarAvatarDescritpionMeta の3つのファイルは、後で使用することになるので Ctrl+D で複製し、独立したファイルとして扱えるようにしておきます。

※ .vrm 内のアセットは Edit > Duplicate で独立したファイルとして扱えるようにしておく

※ VRM バージョン 0.53 では Prefab に内包されていますが、最新バージョンだと最初から独立したファイルとして扱えるようになっていますね。

Fbx の入れ替えが可能なシーンを作る

ここからは Unity らしいシーンを構築していきながら、無用な複製ファイルを削除してプロジェクトを整理していきます。

--

まずは .vrm インポートで作られたプレハブをヒエラルキーに追加して、コンポーネントに設定されている MetaVrmAvatar x2、AvatarDescription の参照先を、前の工程で複製したアセットファイルに差し替えます。
※ メッシュは削除することになるので、マテリアルはひとまず置いておきます。

あわせて、VRM First PersonRenderers は気が付いたら参照が外れていてエラーの原因になるなど厄介なので、Size を 0 にして全ての参照を消しておきます。アバター利用がないなら、二度と触らなくていいと思います。

※ デフォルトで全てのレンダラーが追加されていますが、VRM オーサリングの最後の最後に、必要なものだけを追加しましょう。忘れがちですが… アバター利用がない限りは必要にはなりませんし、ある程度は VRM 側が自動で対応してくれるようです。

※ 各 VRM コンポーネントの参照先を更新する(Inspector 太字部分)

続いて、Hierarchy の VRM ルートノードを右クリック > Unpack Prefab して、secondary 以外を削除し、Fbx モデルデータをルートノードの子供としてヒエラルキーに追加します。

※ モデルデータを Fbx への参照に切り替えた状態(青字部分)

これでメッシュは Fbx ファイルを参照している状態になるので、究極的には Fbx モデルの GameObject(unitychan_Fbx)を入れ替えて、VRM アバターを別のメッシュ・スケルトン構造に変更することも可能になります。

VRM アセットの更新

VRM の階層構造を変更すると、VRM ルートノードにアタッチされた Animator(Avatar) のボーンへの参照が切れた状態になるので、VrmAvatar.asset ファイルは更新が必要になります。

あわせて、VRM Blend Shape Proxy で使われている Blend Shape Avatar/Clip のプレハブ参照が .vrm ファイルになっているので、Fbx ファイルに変更する必要もあります。

※ Animator にエラーが出ているので Avatar を更新する必要がある

ブレンドシェイプの設定

アセットの更新が済んだら取り急ぎ書き出して問題の有無を確認、としたいところですが、エラー対策をしておかないと VRM への書き出しが出来ないことがあるので、先にブレンドシェイプの設定をしておきます。

インスペクタースクリプトの更新

FBX-Linked VRM の場合、PreviewEditor.cs を少し弄らないと Blend Shape Clip のインスペクター下部に表示されるプレビューやフェイシャルのスライダーが機能しません。
(プレビューと設定が出来ないだけで、設定済みのデータを扱うだけなら問題はない)

編集機能を使用可能にするためには、以下から更新されたスクリプトをダウンロードして上書きします。

UniVRM v0.53 以外を使用していて上記のファイルをそのまま使うことに抵抗がある場合は、以下の変更内容を参考にスクリプトを更新します。

※ 文字列操作を元にプレハブを取得する前に、コンポーネントの参照を辿って取得を試みるようにしています。

VRM > UniVRM > Editor > BlendShape > PreviewEditor.cs の97行目あたりに、

var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);


// ↓ ↓ ↓ 追加 ↓ ↓ ↓
if(prefab == null && 0 < (target as BlendShapeAvatar).Clips.Count)
{
   prefab = (target as BlendShapeAvatar).Clips[0].Prefab;
}
// ↑ ↑ ↑ 追加 ↑ ↑ ↑


if (prefab == null)
{
   var parent = UniGLTF.UnityPath.FromUnityPath(assetPath).Parent;
   var prefabPath = parent.Parent.Child(parent.FileNameWithoutExtension + ".prefab");
   prefab = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath.Value);
}
return prefab;

を追加します。

VRM ブレンドシェイプのエラー対策

VRM エクスポート時のエラー対策の為、Neutral などのウェイト設定が必要のない表情、将来的に使うかもしれないが今は設定しない表情にも、何かしらのウェイトを 0 で追加しておきます。

※ Neutral は全てのウェイトを 0 として登録する…?

プロジェクトの整理

ここまでくると、.vrm エクスポート・インポートで作成された無用なファイル群を削除できるようになります。

VRM コンポーネント収集のためだけの仮 .vrm ファイル、加えて ***.Meshes***.Textures フォルダも必要のない複製ファイルなので削除しておきます。

マテリアルが VRM とそれ以外の用途で共通であれば、***.Materials も無用なので削除してしまいましょう。

※ 無用な複製がなくなった状態

書き出しテスト

ファイルの整理が済んだら一度 VRM として書き出して、T ポーズや BVH のテストアニメーションが適切に再生されるかテストをしておきます。

※ ここで上手くいかない場合、VRM > UniVRM-*** > Freeze T-Pose を実行してエラー無しでキャラクターが T ポーズになるかどうかを確認し、エラーが出る場合は解消します。

--

なお、自身で T ポーズを付けるワークフローにも対応しているので、その場合は Force T-Pose をオンにせず、Pose Freeze のみオンにして書き出します。

※ エクスポート時は Force T-Pose(必要な場合)と Pose Freeze をオンにする

書き出しに成功すれば、通常のワークフローで作成した VRM と同様にビューアーで表示することが出来ます。

※ T ポーズで腕が水平になっていれば問題ない

おまけ: Unity エディター上での簡易プレビュー

上記の画像は VRM.SamplesSimpleViewer.unity をエディター上で実行して VRM ファイルを確認しているところですが、SimpleViewer.unity はビルドターゲットが非 Windows 環境になっているプロジェクトでの実行時に VRM ファイルを選択する事が出来ません。

※ Windows で Unity エディターを実行していても、ビルドターゲットがスマホになっている場合は VRM ファイルの選択ダイアログが表示されません。

以下を参考にスクリプトを更新すると、ビルドターゲットがスマホだったり macOS だったりした場合でも任意の VRM ファイルを選択してプレビューできるようになります。

FileDialogForWindows.FileDialog がある部分に #elif UNITY_EDITOR... を追加。

#if UNITY_STANDALONE_WIN
   var path = FileDialogForWindows.FileDialog("open VRM", "vrm", "glb", "bvh");


// ↓ ↓ ↓ 追加 ↓ ↓ ↓
#elif UNITY_EDITOR
   var path = UnityEditor.EditorUtility.OpenFilePanel("Load VRM", "", "vrm");
// ↑ ↑ ↑ 追加 ↑ ↑ ↑


#else
   var path = Application.dataPath + "/default.vrm";
#endif

おまけ2: macOS / Linux での VRM ファイルのプレビュー

Windows 版のみ提供されている公式の VRM ビューアーは、表情の確認ができるなど UniVRM / VRM.Samples の SimpleViewer.unity よりも高機能なので、最終チェックには必須のアプリです。

macOS でも動作するようにアップデートしたアプリは以下からダウンロード出来ます。

VRM Spring Bone の作成

VRM 書き出しテストでボディーに問題が無ければ Spring Bone を追加して揺れものの設定をしてきます。

プレハブにコンポーネントを追加する際の注意点

ここからプレハブに対してコンポーネントを追加していくことになりますが、プレハブ由来の GameObject に対して直接コンポーネントを追加する、ということは控えます。
※ これは VRM データ作成に限らず、ですね。

プレハブ由来の GameObject に対して直接コンポーネントを追加すると、プレハブ更新でその GameObject がなくなった時にコンポーネントが消失してしまいます。

直接付与するのではなく、GameObject を追加してそこにコンポーネントを付与するようにしておけば、更新で GameObject がなくなったとしてもルートに吐き出されて残るので、それを使ってどうにかすることができます。

※ Fbx のルートもプレハブ由来ですが、ほぼ確実に存在するのでコンポーネントを付与しても大丈夫です。
(ルートを作らないオプションもありますが、使っている人はいないでしょう。。。?)

※ 階層構造の変化については、後半にある Fbx 上書きテストで実際の挙動が確認できます。

GameObject が増えると処理負荷は多少は上がることになりますが、コリジョンしか持ってない GameObject のコンポーネントを親 GameObject に移植する、という機能を用意すれば良いだけの話なので、使いまわし易さ、データ構造を説明するドキュメントを用意するまでもない分かり易さを優先します。

--

揺れ物の設定は VRM エクスポーターが secondary ノードに纏めてくれるので、VRM 作成用シーンでは自分の扱いやすい状態で管理しても問題ありません。
secondary ノード自体、VRM 作成用シーンに残す必要はないようです。

ひとつの GameObject に同一コンポーネントを複数追加した状態だと、特定の VRM Spring Bone に対して Root Bone や Collider Group をスクリプトからアサイン、という事も難しくなるので、余程の事情が無い限りは Spring Bone コンポーネントひとつにつき GameObject をひとつ作って作業します。

※ Spring Bone 毎に GameObject を分けておいた方が管理・再利用がしやすい

VRM Spring Bone Collider Group の作成

続いてコライダーの追加もしていきます。

Unity シーンの構造的にはプレハブの階層に Collider を追加した状態になっていますが、特に問題なく VRM への書き出しが可能です。※ 上図ヒエラルキーウインドウ参照

※ コライダーを生成している様子

※ Spring Bone を設定した VRM ファイルをプレビュー表示

VRM Spring Bone の設定

コライダーの生成が終わったら、VRM Spring Bone の設定も済ませます。

その他の VRM コンポーネントを設定

揺れものの設定が済んだら、その他の VRM コンポーネントの設定を行います。

VRM Look At Blend Shape Applier は忘れがちなので特に注意します。

  • VRM ルートノードにアサインされているべきコンポーネント一覧
    • VRM Meta
    • VRM Humanoid Description
    • Animator
    • VRM Blend Shape Proxy
    • VRM First Person
    • VRM Look At Head
    • VRM Look At Bone Applyer
      • または VRM Look At Blend Shape Applyer

各コンポーネントの詳細は、以下の公式サイトで確認できます。

各種アセットファイルの共用について

VRM Meta のアセットファイルは大した情報量ではないので、共用でも書き出しの度に確認・編集でも問題はなさそうです。

Blend Shape の設定ファイル群も同様に共用可能ですが、無用なトラブルを避ける為にはキャラクターそれぞれでユニークなものを使った方が良いでしょう。ファイル自体を複製しても参照先は複製元のファイルのままなので、ちょっと準備が面倒ではあります…。

書き出した VRM の構造

VRM コンポーネントの設定が済んだら、使用・配布が可能な最終 .vrm を書き出せる状態になっています。

書き出した最終 .vrm ファイルを Unity に読み戻すと、キャラクターは T ポーズになり Spring Bone コンポーネントはすべて secondary ノードに集約され、元々コンポーネントを持っていた SpringBone *** も残った状態になっています。

※ 書き出した FBX-Linked な .vrm を Unity に読み込んだ状態

通常のワークフローで作成した VRM と同様の .vrm を作成することが出来ました。

Fbx ファイル上書きテスト

最後に、いくつかのシチュエーションを想定した .fbx 差し替えテストをご紹介します。

メッシュ変更

後ろ髪の毛先はエクスポートミスですが、再エクスポートすれば良いだけなので気楽なものです。

※ 髪型チェンジ

メッシュの増減

肩に SD キャラを乗せました。

※ 肩パーツ追加

スキンウェイト更新

SD キャラたちは肩のボーンの影響を受けるだけでいいところ、腕のボーンの影響も受ける状態でエクスポートしてしまいました。

:sob::sob::sob:

UV 調整

微調整しない、なんてことはないですよね。

※ カットバイ対応・イベント毎の対応も気軽に

ブレンドシェイプ追加

Maya から書き出すと blendShape1. ってノード名が接頭辞として付くようになっちゃって困っているんですが、どうしたらいいんでしょうか。

※ ユニティちゃん洗顔後

階層構造の変更

Prefab 更新でペアレントが見つからなくなった GameObject は、Fbx ルートの直下に吐き出されます。
※ その後元の階層構造に戻したとしても、吐き出された GameObject は元には戻りません。

これは Unity でのアセット作成全般に言えることですが、GameObject を新規で追加してさえいれば後からどうにでもなるので、アセット由来で生成された GameObject に直接コンポーネントを追加するような事は、余程のことが無い限りは控えましょう。

(一度パブリッシュしたらタイポ修正を含めて変更はしないで欲しいですよね)

※ 元々の親 GameObject が見つからないオブジェクトがルートに吐き出される様子

おわりに

ここで紹介した手法は FBX の参照維持のため、意地になって結構むりくりやっている部分もあります。
とはいえ VRM 公式のエディタースクリプトへの対応が主ではあるので、書き出した VRM が変なことになっているという事はないと思います。

FBX-Linked VRM が仮に何か問題になるとしたら、

  • VRM ルートノードに付いてる Animator の Avatar まわり

    • 子供の Fbx ルートにも Animator を付けっぱなしで作業しているので、うまく行かなかったらエクスポート時に削除して書き出す、を試してみる
  • Blend Shape Clip の Relative Path まわり

    • Blend Shape Clip のインスペクタープレビューの仕様上、メッシュの相対パスの起点を Fbx ルート <=> VRM ルート間で切り替えている
    • エクスポート時は VRM ルートからの相対パスにする必要があり、その状態だと Inspector ではプレビュー・パラメーターが適切に表示されない(データ上は問題ない)
    • エディタースクリプトなのに表示のついでにデータ弄っちゃう系が v0.53 以降で追加されると、ノードを選択して Inspector が描画されるだけでデータが壊れる可能性はあるかも
      • Debug モードで Render Queue を弄って Normal モードの Inspector で表示すると勝手に元に戻るあれ

のあたりが怪しいです。

ともあれ、VRM を作っていて困ったときは FBX-Linked なこの手法に限らず、VRM > VRM-*** > Freeze T-Pose を実行してエラーが出ないかを確認し、あれば対処というイテレーションが解決の近道だと思います。

--

以上です。お疲れ様でした。

各種ライセンス情報

この記事内で使用、改変しているモデルデータのライセンス情報です。

ユニティちゃん

この記事中で使用されているユニティちゃんは、ユニティちゃんライセンス条項の元に提供されています。

いつき / 制服

花咲うらら氏の公開されているモデルデータです。詳細は以下のリンク先で確認できます。

あわせてどうぞ

17
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
21