vrm-c / UniVRM

UniVRM is a gltf-based VRM format implementation for Unity. English is here https://vrm.dev/en/ . 日本語 はこちら https://vrm.dev/
https://vrm.dev/en
MIT License
2.57k stars 417 forks source link

ルートオブジェクトが非アクティブのVRMモデルをExportするとImportできないVRMファイルが出力される #398

Closed karukaru808 closed 4 years ago

karukaru808 commented 4 years ago

バグについて

インポートされたVRMモデルをヒエラルキ上に配置し、ルートオブジェクトを非アクティブにした状態でExport humanoidを行うと、ImportできないVRMファイルが生成されます。 Export時には一切エラーなどは出ず、Import時に以下のエラーが出ます。

KeyNotFoundException: The given key was not present in the dictionary.
DepthFirstScheduler.Schedulable`1[T].ExecuteAll () (at Assets/VRM/DepthFirstScheduler/Schedulable.cs:119)
UniGLTF.ImporterContext.Load () (at Assets/VRM/UniGLTF/Scripts/IO/ImporterContext.cs:438)
VRM.vrmAssetPostprocessor+<>c__DisplayClass1_0.<ImportVrm>b__0 () (at Assets/VRM/UniVRM/Editor/Format/vrmAssetPostprocessor.cs:51)
UnityEditor.EditorApplication.Internal_CallDelayFunctions () (at C:/buildslave/unity/build/Editor/Mono/EditorApplication.cs:209)

またモデルによっては上記エラーは出力されず、Import自体はエラーなどなく終了しますが、SkinnedMeshRendererコンポーネントが一切アタッチされていないPrefabが生成されます。

FBXモデルをヒエラルキ上に配置し、ルートオブジェクトを非アクティブにした状態でExportした場合は、正常に読み込めるVRMファイルが出力されます。

再現方法

エラーが出力される場合

  1. https://3d.nicovideo.jp/works/td32797 からニコニ立体ちゃんのVRMファイルをDLしてくる
  2. VRMファイルをImportする
  3. 生成されたPrefabをヒエラルキ上に配置し、ルートオブジェクトを非アクティブにする
  4. Export humanoidし、出力されたVRMファイルをImportする
  5. エラーが出力されImportが途中で終了する

SkinnedMeshRendererコンポーネントがアタッチされない場合

  1. https://assetstore.unity.com/packages/3d/characters/unity-chan-model-18705 からユニティちゃんのFBXモデルをDL&Importする
  2. ヒエラルキ上に配置し、ルートオブジェクトを非アクティブにする
  3. Export humanoidし、出力されたVRMファイルをImportする
  4. 生成されたPrefabをヒエラルキ上に配置する
    この時生成されたPrefabを確認すると、正常にVRMモデルが読み込めています。
  5. ルートオブジェクトを非アクティブにする
  6. Export humanoidし、出力されたVRMファイルをImportする
  7. エラーなどなくImportは終了するが、SkinnedMeshRendererコンポーネントが一切アタッチされていないPrefabが出力される

期待する動作

正常に読み込めるVRMファイルが出力されること。 もしくはルートオブジェクトが非アクティブの場合は、警告などを表示しExport humanoidできないようにする。

環境情報

追加の状況・背景

エラー内容からVRMファイルを軽く確認したところ、正常にImportできるVRMファイルには"mesh"キーと"skin"キーがあるのですが、ImportできないVRMファイルにはそれらが記述されていません。 またImportがTextureまで正常に終わっており、(恐らく)Meshの生成時にエラーが出力されているため、上記内容と合わせて考えるとMeshのExport時に必要な情報が出力されていないのが原因かと思われます。

左が正常にImportできるVRMファイル、右がImportできないVRMファイルで、Diffを取った結果です。 コメント 2020-05-16 231402

hiroj commented 4 years ago

ご報告ありがとうございます。 現在は非アクティブなオブジェクトとその子のMeshは意図的にExportしない仕様になっています。 https://github.com/vrm-c/UniVRM/wiki/ReleaseNote-v0.46(ja)#%E9%9D%9E%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%83%E3%83%97

そのためRootを非アクティブにすると全てのMeshを書き込まないことになり、Mesh参照でエラーになっているようです。 アクティブ状態のMeshオブジェクトが1つも無い場合はエラーになり、出力出来ないように変更いたします。

ousttrue commented 4 years ago

動作を確認しました。

UniVRM-0.55 とリポジトリに付属する Tests/Models/AliciaSolid_vrm-0.51.vrm で実験したところ、 import 時に KeyNotFoundException が再現しました。 import時に、 BlendShapeClip が存在しない Mesh を参照しているのが原因でした。

なので Alicia の場合、face のみを非アクティブにすることでも再現しました。 まず、非アクティブな Mesh を参照する BlendShape を除外するところから修正します。

ousttrue commented 4 years ago

複数のパターンがあるようです。 非アクティブ な Mesh を除外する経路

このあたり修正します。

hiroj commented 4 years ago

401でExport時に警告が出るようになりましたので、よろしければご確認ください。

v0.56から適用されます。 もし問題がある場合は別のissueか、またはこのissueを再Openして頂けると助かります。