vrm-c / vrm.dev

Home Page:https://vrm.dev/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ランタイムインポーターのサンプルの修正

gpsnmeajp opened this issue · comments

UniVRM 0.79および0.80でサンプルを実行しましたが、GltfParserが存在せず、ビルドが通りません。
また、オンメモリで読み込む際に必要となるであろうGlbLowLevelParserに関して説明が見当たりませんでした。

実際に動くよう修正してみましたので、以下の修正版を提案致します。
Unity 2019.4.29f1および、UniVRM 0.79で動作を確認しました。

using UniGLTF;
using UnityEngine;

namespace VRM.Samples
{
    public sealed class LoadVrmSample : MonoBehaviour
    {
        [SerializeField] private string _vrmFilePath;
        private GameObject _vrmGameObject;

        private void Start()
        {
            _vrmGameObject = LoadVrm(_vrmFilePath);
        }

        private void OnDestroy()
        {
            DestroyVrm(_vrmGameObject);
        }

        private GameObject LoadVrm(string vrmFilePath)
        {
            // 1. GlbFileParser を呼び出します。
            //    GlbFileParser はファイルから JSON 情報とバイナリデータを読み出し、GltfDataとして返却します。
            var parser = new GlbFileParser(vrmFilePath);
            var gltfData = parser.Parse();

            //オンメモリで読み込む場合、代わりに以下のように行います。
            //dataにはbyte[]としてVRMデータを代入しておきます。
            //var parser = new GlbLowLevelParser(string.Empty, data);
            //var gltfData = parser.Parse();

            // 2. GltfDataを引数にして VRMImporterContext を作成します。
            //    VRMImporterContext は VRM のロードを実際に行うクラスです。
            using (var context = new VRMImporterContext(gltfData))
            {
                // 3. Load 関数を呼び出し、VRM の GameObject を生成します。
                RuntimeGltfInstance instance = context.Load(); // <- `v0.77` でここが変わります。

                // 非同期版 async 関数の中で下記のようにしてください
                // RuntimeGltfInstance instance = await context.LoadAsync();

                // 4. (任意) SkinnedMeshRenderer の UpdateWhenOffscreen を有効にできる便利関数です。
                //    https://docs.unity3d.com/2019.4/Documentation/ScriptReference/SkinnedMeshRenderer-updateWhenOffscreen.html
                instance.EnableUpdateWhenOffscreen(); // <- ImporterContext から RuntimeGltfInstance に移動しました。

                // 5. VRM モデルを表示します。
                instance.ShowMeshes(); // <- ImporterContext から RuntimeGltfInstance に移動しました。

                // 6. Root の GameObject を return します。
                //    Root の GameObject とは VRMMeta コンポーネントが付与されている GameObject のことです。
                return instance.Root; // <- ImporterContext から RuntimeGltfInstance に移動しました。
            }
            // 7. using スコープを抜けて context が破棄されると、 VRMImporterContext が保持する UnityEngine.Object リソースが破棄されます。
            //    このとき破棄されるリソースは、 glTF ファイルには含まれているが VRM の GameObject には割り当てられていないテクスチャなどです。
            //    手順 6. で VRM の GameObject に紐付けたリソースは、ここでは破棄されません。
        }

        private void DestroyVrm(GameObject vrmGameObject)
        {
            // 8. 生成された VRM の GameObject を破棄します。
            //    GameObject を破棄すれば、紐づくリソース (Texture, Material, Mesh, etc) も破棄されます。
            UnityEngine.Object.Destroy(vrmGameObject);
        }
    }
}

ご指摘ありがとうございます。

https://vrm-c.github.io/UniVRM/
にプログラミング関連のドキュメントを整理することにしました。