コード例 #1
0
        public void MaterialImporterTest()
        {
            var parser = new GltfParser();

            parser.ParsePath(AliciaPath);
            var vrmImporter   = new VRMImporterContext(parser, null);
            var materialParam = new VRMMaterialImporter(vrmImporter.VRM).GetMaterialParam(parser, 0);

            Assert.AreEqual("VRM/MToon", materialParam.ShaderName);
            Assert.AreEqual("Alicia_body", materialParam.TextureSlots["_MainTex"].UnityObjectName);

            var(key, value) = materialParam.EnumerateSubAssetKeyValue().First();
            Assert.AreEqual(new SubAssetKey(typeof(Texture2D), "Alicia_body"), key);
        }
コード例 #2
0
        private static void LoadHumanoidObsolete(VRMImporterContext context)
        {
            var parsed   = UniJSON.JsonParser.Parse(context.Json)["extensions"]["VRM"];
            var skeleton = context.Root.transform.Traverse().Select(x => ToSkeletonBone(x)).ToArray();

            var description = new HumanDescription
            {
                human = parsed[HUMANOID_KEY]["bones"]
                        .ObjectItems
                        .Select(x => new { x.Key, Index = x.Value.Value.GetInt32() })
                        .Where(x => x.Index != -1)
                        .Select(x =>
                {
                    var humanBone = EnumUtil.TryParseOrDefault <HumanBodyBones>(x.Key);
                    var hb        = new HumanBone
                    {
                        boneName  = context.Nodes[x.Index].name,
                        humanName = ToHumanBoneName(humanBone)
                    };
                    hb.limit.useDefaultValues = true;
                    return(hb);
                }).ToArray(),
                skeleton      = skeleton,
                lowerArmTwist = 0.5f,
                upperArmTwist = 0.5f,
                upperLegTwist = 0.5f,
                lowerLegTwist = 0.5f,
                armStretch    = 0.05f,
                legStretch    = 0.05f,
                feetSpacing   = 0.0f,
            };

            context.HumanoidAvatar      = AvatarBuilder.BuildHumanAvatar(context.Root, description);
            context.HumanoidAvatar.name = "VrmAvatar";

            context.AvatarDescription      = UniHumanoid.AvatarDescription.CreateFrom(description);
            context.AvatarDescription.name = "AvatarDescription";
            var humanoid = context.Root.AddComponent <VRMHumanoidDescription>();

            humanoid.Avatar      = context.HumanoidAvatar;
            humanoid.Description = context.AvatarDescription;

            var animator = context.Root.GetComponent <Animator>();

            if (animator == null)
            {
                animator = context.Root.AddComponent <Animator>();
            }
            animator.avatar = context.HumanoidAvatar;
        }
コード例 #3
0
        static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
        {
            foreach (string path in importedAssets)
            {
                var ext = Path.GetExtension(path).ToLower();
                if (ext == ".vrm")
                {
                    var context = new VRMImporterContext(path);

                    context.ParseVrm(File.ReadAllBytes(context.Path));

                    //
                    // https://answers.unity.com/questions/647615/how-to-update-import-settings-for-newly-created-as.html
                    //
                    for (int i = 0; i < context.GLTF.textures.Count; ++i)
                    {
                        var x     = context.GLTF.textures[i];
                        var image = context.GLTF.images[x.source];
                        if (string.IsNullOrEmpty(image.uri))
                        {
                            // glb buffer
                            var folder = context.GetAssetFolder(".Textures").AssetPathToFullPath();
                            if (!Directory.Exists(folder))
                            {
                                UnityEditor.AssetDatabase.CreateFolder(context.GLTF.baseDir, Path.GetFileNameWithoutExtension(context.Path) + ".Textures");
                                //Directory.CreateDirectory(folder);
                            }

                            var textureName = string.IsNullOrEmpty(image.extra.name) ? string.Format("buffer#{0:00}", i) : image.extra.name;
                            var png         = Path.Combine(folder, textureName + ".png");
                            var byteSegment = context.GLTF.GetViewBytes(image.bufferView);
                            File.WriteAllBytes(png, byteSegment.ToArray());
                            var assetPath = png.ToUnityRelativePath();
                            //Debug.LogFormat("import asset {0}", assetPath);
                            UnityEditor.AssetDatabase.ImportAsset(assetPath, UnityEditor.ImportAssetOptions.ForceUpdate);
                            UnityEditor.AssetDatabase.Refresh();
                            image.uri = assetPath.Substring(context.GLTF.baseDir.Length + 1);
                        }
                    }

                    EditorApplication.delayCall += () =>
                    {
                        // delay and can import png texture
                        VRMImporter.LoadFromBytes(context);
                        context.SaveAsAsset();
                        context.Destroy(false);
                    };
                }
            }
        }
コード例 #4
0
        void LoadAsync(VRMImporterContext context, ArraySegment <byte> dataChunk)
        {
#if true
            var now = Time.time;
            VRMImporter.LoadVrmAsync(context, dataChunk, go => {
                var delta = Time.time - now;
                Debug.LogFormat("LoadVrmAsync {0:0.0} seconds", delta);
                OnLoaded(go);
            });
#else
            // ローカルファイルシステムからロードします
            VRMImporter.LoadVrmAsync(path, OnLoaded);
#endif
        }
コード例 #5
0
        public static async Task <RuntimeGltfInstance> LoadAsync(string path,
                                                                 IAwaitCaller awaitCaller = null,
                                                                 MaterialGeneratorCallback materialGeneratorCallback = null,
                                                                 MetaCallback metaCallback = null
                                                                 )
        {
            if (!File.Exists(path))
            {
                throw new FileNotFoundException(path);
            }

            if (awaitCaller == null)
            {
                Debug.LogWarning("VrmUtility.LoadAsync: awaitCaller argument is null. ImmediateCaller is used as the default fallback. When playing, we recommend RuntimeOnlyAwaitCaller.");
                awaitCaller = new ImmediateCaller();
            }

            using (GltfData data = new AutoGltfFileParser(path).Parse())
            {
                try
                {
                    var vrm = new VRMData(data);
                    IMaterialDescriptorGenerator materialGen = default;
                    if (materialGeneratorCallback != null)
                    {
                        materialGen = materialGeneratorCallback(vrm.VrmExtension);
                    }
                    using (var loader = new VRMImporterContext(vrm, materialGenerator: materialGen))
                    {
                        if (metaCallback != null)
                        {
                            var meta = await loader.ReadMetaAsync(awaitCaller, true);

                            metaCallback(meta);
                        }
                        return(await loader.LoadAsync(awaitCaller));
                    }
                }
                catch (NotVrm0Exception)
                {
                    // retry
                    Debug.LogWarning("file extension is vrm. but not vrm ?");
                    using (var loader = new UniGLTF.ImporterContext(data))
                    {
                        return(await loader.LoadAsync(awaitCaller));
                    }
                }
            }
        }
コード例 #6
0
        public void TraverseRenderers(VRMImporterContext context = null)
        {
            var rendererComponents = transform.GetComponentsInChildren <Renderer>();

            foreach (var renderer in rendererComponents)
            {
                Renderers.Add(new RendererFirstPersonFlags
                {
                    Renderer        = renderer,
                    FirstPersonFlag = context == null
                        ? FirstPersonFlag.Auto
                        : GetFirstPersonFlag(context, renderer)
                });
            }
        }
コード例 #7
0
        static IEnumerator LoadMeshes(VRMImporterContext context)
        {
            for (int i = 0; i < context.GLTF.meshes.Count; ++i)
            {
                var meshWithMaterials = gltfImporter.ImportMesh(context, i);
                var mesh = meshWithMaterials.Mesh;
                if (string.IsNullOrEmpty(mesh.name))
                {
                    mesh.name = string.Format("UniGLTF import#{0}", i);
                }
                context.Meshes.Add(meshWithMaterials);

                yield return(null);
            }
        }
コード例 #8
0
        public void MeshCoyTest()
        {
            var path    = UniGLTF.UnityPath.FromUnityPath("Models/Alicia_vrm-0.40/AliciaSolid_vrm-0.40.vrm");
            var context = new VRMImporterContext();

            context.ParseGlb(File.ReadAllBytes(path.FullPath));
            VRMImporter.LoadFromBytes(context);

            foreach (var mesh in context.Meshes)
            {
                var src = mesh.Mesh;
                var dst = src.Copy(true);
                MeshTests.MeshEquals(src, dst);
            }
        }
コード例 #9
0
        public void MaterialImporterTest()
        {
            var path = AliciaPath;

            using (var data = new GlbFileParser(path).Parse())
            {
                var vrmImporter   = new VRMImporterContext(new VRMData(data), null);
                var materialParam = new VRMMaterialDescriptorGenerator(vrmImporter.VRM).Get(data, 0);
                Assert.AreEqual("VRM/MToon", materialParam.ShaderName);
                Assert.AreEqual("Alicia_body", materialParam.TextureSlots["_MainTex"].UnityObjectName);

                var(key, value) = materialParam.EnumerateSubAssetKeyValue().First();
                Assert.AreEqual(new SubAssetKey(typeof(Texture), "Alicia_body"), key);
            }
        }
コード例 #10
0
ファイル: VRMImporterMenu.cs プロジェクト: Santarh/UniVRM
        static void ImportRuntime(string path)
        {
            // load into scene
            var data = new GlbFileParser(path).Parse();
            // VRM extension を parse します
            var vrm = new VRMData(data);

            using (var context = new VRMImporterContext(vrm))
            {
                var loaded = context.Load();
                loaded.EnableUpdateWhenOffscreen();
                loaded.ShowMeshes();
                Selection.activeGameObject = loaded.gameObject;
            }
        }
コード例 #11
0
 static IEnumerator LoadMaterials(VRMImporterContext context)
 {
     if (context.GLTF.materials == null || !context.GLTF.materials.Any())
     {
         context.Materials.Add(context.CreateMaterial(context, 0));
     }
     else
     {
         for (int i = 0; i < context.GLTF.materials.Count; ++i)
         {
             context.Materials.Add(context.CreateMaterial(context, i));
             yield return(null);
         }
     }
 }
コード例 #12
0
        public void MToonMaterialParamTest()
        {
            if (!VRMTestAssets.TryGetPath("Models/VRoid/VictoriaRubin/VictoriaRubin.vrm", out string path))
            {
                return;
            }

            var data = new GlbFileParser(path).Parse();
            var vrm  = new VRMData(data);

            var importer = new VRMImporterContext(vrm, null);

            Assert.AreEqual(73, vrm.Data.GLTF.materials.Count);
            Assert.True(VRMMToonMaterialImporter.TryCreateParam(vrm.Data, importer.VRM, 0, out MaterialDescriptor matDesc));
        }
コード例 #13
0
        void LoadAsync(VRMImporterContext context)
        {
#if true
            var now = Time.time;
            context.LoadAsync(_ =>
            {
                var delta = Time.time - now;
                Debug.LogFormat("LoadAsync {0:0.0} seconds", delta);
                OnLoaded(context);
            });
#else
            // ローカルファイルシステムからロードします
            VRMImporter.LoadVrmAsync(path, OnLoaded);
#endif
        }
コード例 #14
0
ファイル: VRMFirstPerson.cs プロジェクト: mu-777/UniVRM
 public void TraverseRenderers(VRMImporterContext context = null)
 {
     Renderers = Traverse(transform)
                 .Select(x => x.GetComponent <Renderer>())
                 .Where(x => x != null)
                 .Select(x => new RendererFirstPersonFlags
     {
         Renderer        = x,
         FirstPersonFlag = context == null
                 ? FirstPersonFlag.Auto
                 : GetFirstPersonFlag(context, x)
     })
                 .ToList()
     ;
 }
コード例 #15
0
        static void ImportRuntime(string path)
        {
            // load into scene
            var parser = new GltfParser();

            parser.ParsePath(path);

            using (var context = new VRMImporterContext(parser))
            {
                context.Load();
                context.EnableUpdateWhenOffscreen();
                context.ShowMeshes();
                context.DisposeOnGameObjectDestroyed();
                Selection.activeGameObject = context.Root;
            }
        }
コード例 #16
0
ファイル: VRMImporterMenu.cs プロジェクト: mirrorshade/UniVRM
        static void Import(string readPath, UnityPath prefabPath)
        {
            var bytes   = File.ReadAllBytes(readPath);
            var context = new VRMImporterContext(UnityPath.FromFullpath(readPath));

            context.ParseGlb(File.ReadAllBytes(readPath));
            context.SaveTexturesAsPng(prefabPath);

            EditorApplication.delayCall += () =>
            {
                // delay and can import png texture
                VRMImporter.LoadFromBytes(context);
                context.SaveAsAsset(prefabPath);
                context.Destroy(false);
            };
        }
コード例 #17
0
        static void ImportVrm(UnityPath path)
        {
            if (!path.IsUnderAssetsFolder)
            {
                throw new Exception();
            }

            var parser = new GltfParser();

            try
            {
                parser.ParseGlb(File.ReadAllBytes(path.FullPath));
            }
            catch (KeyNotFoundException)
            {
                // invalid VRM-0.X.
                // maybe VRM-1.0.do nothing
                return;
            }

            var prefabPath = path.Parent.Child(path.FileNameWithoutExtension + ".prefab");

            // save texture assets !
            LoadTextureAsyncFunc textureLoader = async(caller, textureIndex, used) =>
            {
                var gltfTexture = parser.GLTF.textures[textureIndex];
                var gltfImage   = parser.GLTF.images[gltfTexture.source];
                var assetPath   = prefabPath.Parent.Child(gltfImage.uri);
                var texture     = await UniGLTF.AssetTextureLoader.LoadTaskAsync(assetPath, parser.GLTF, textureIndex);

                return(new TextureLoadInfo(texture, used, false));
            };
            var context = new VRMImporterContext(parser, textureLoader);
            var editor  = new VRMEditorImporterContext(context);

            editor.ExtractImages(prefabPath);

            EditorApplication.delayCall += () =>
            {
                //
                // after textures imported
                //
                context.Load();
                editor.SaveAsAsset(prefabPath);
                editor.Dispose();
            };
        }
コード例 #18
0
ファイル: ViewerUI.cs プロジェクト: Maple614/Myo_Capture
        void LoadModel(string path)
        {
            if (!File.Exists(path))
            {
                return;
            }

            Debug.LogFormat("{0}", path);
            var ext = Path.GetExtension(path).ToLower();

            switch (ext)
            {
            case ".vrm":
            {
                var context = new VRMImporterContext();

                var file = File.ReadAllBytes(path);
                context.ParseGlb(file);

                m_texts.UpdateMeta(context);
                //UniJSON.JsonParser.Parse(context.Json);

                VRMImporter.LoadVrmAsync(context, SetModel);

                break;
            }

            case ".glb":
            {
                var context = new UniGLTF.ImporterContext();

                var file = File.ReadAllBytes(path);
                context.ParseGlb(file);

                UniGLTF.gltfImporter.Load(context);
                context.ShowMeshes();
                SetModel(context.Root);

                break;
            }

            default:
                Debug.LogWarningFormat("unknown file type: {0}", path);
                break;
            }
        }
コード例 #19
0
        public void OnImported(VRMImporterContext context)
        {
            var animator = GetComponent <Animator>();

            if (animator != null)
            {
                LeftEye  = OffsetOnTransform.Create(animator.GetBoneTransform(HumanBodyBones.LeftEye));
                RightEye = OffsetOnTransform.Create(animator.GetBoneTransform(HumanBodyBones.RightEye));
            }

            var gltfFirstPerson = context.VRM.firstPerson;

            HorizontalInner.Apply(gltfFirstPerson.lookAtHorizontalInner);
            HorizontalOuter.Apply(gltfFirstPerson.lookAtHorizontalOuter);
            VerticalDown.Apply(gltfFirstPerson.lookAtVerticalDown);
            VerticalUp.Apply(gltfFirstPerson.lookAtVerticalUp);
        }
コード例 #20
0
        /// <summary>
        /// メタが不要な場合のローダー
        /// </summary>
        void LoadVRMClicked_without_meta()
        {
#if UNITY_STANDALONE_WIN
            var path = FileDialogForWindows.FileDialog("open VRM", ".vrm");
#else
            var path = Application.dataPath + "/default.vrm";
#endif
            if (string.IsNullOrEmpty(path))
            {
                return;
            }

#if true
            var bytes = File.ReadAllBytes(path);
            // なんらかの方法でByte列を得た

            var context = new VRMImporterContext();

            // GLB形式でJSONを取得しParseします
            context.ParseGlb(bytes);

            if (m_loadAsync)
            {
                // ローカルファイルシステムからロードします
                LoadAsync(context);
            }
            else
            {
                context.Load();
                OnLoaded(context);
            }
#else
            // ParseしたJSONをシーンオブジェクトに変換していく
            if (m_loadAsync)
            {
                // ローカルファイルシステムからロードします
                VRMImporter.LoadVrmAsync(path, OnLoaded);
            }
            else
            {
                var root = VRMImporter.LoadFromPath(path);
                OnLoaded(root);
            }
#endif
        }
コード例 #21
0
        public void MToonMaterialParamTest()
        {
            if (!VRMTestAssets.TryGetPath("Models/VRoid/VictoriaRubin/VictoriaRubin.vrm", out string path))
            {
                return;
            }

            var parser = new GltfParser();

            parser.ParsePath(path);

            var importer = new VRMImporterContext(parser, null);

            var materialImporter = new VRMMaterialImporter(importer.VRM);

            Assert.AreEqual(73, parser.GLTF.materials.Count);
            Assert.True(materialImporter.TryCreateParam(parser, 0, out MaterialImportParam param));
        }
コード例 #22
0
        public static void LoadVrmAsync(Byte[] bytes, Action <GameObject> onLoaded, Action <Exception> onError = null, bool show = true)
        {
            var context = new VRMImporterContext();

            using (context.MeasureTime("ParseGlb"))
            {
                context.ParseGlb(bytes);
            }
            context.LoadAsync(_ =>
            {
                if (show)
                {
                    context.ShowMeshes();
                }
                onLoaded(context.Root);
            },
                              onError);
        }
コード例 #23
0
        public static void ImportVrmAndCreatePrefab(string vrmPath, UnityPath prefabPath)
        {
            if (!prefabPath.IsUnderAssetsFolder)
            {
                Debug.LogWarningFormat("out of asset path: {0}", prefabPath);
                return;
            }

            /// <summary>
            /// これは EditorApplication.delayCall により呼び出される。
            ///
            /// * delayCall には UnityEngine.Object 持ち越すことができない
            /// * vrmPath のみを持ち越す
            ///
            /// </summary>
            /// <value></value>
            Action <IEnumerable <UnityPath> > onCompleted = texturePaths =>
            {
                var map = texturePaths
                          .Select(x => x.LoadAsset <Texture>())
                          .ToDictionary(x => new SubAssetKey(x), x => x as UnityEngine.Object);

                // 確実に Dispose するために敢えて再パースしている
                using (var data = new GlbFileParser(vrmPath).Parse())
                    using (var context = new VRMImporterContext(new VRMData(data), externalObjectMap: map))
                    {
                        var editor = new VRMEditorImporterContext(context, prefabPath);
                        foreach (var textureInfo in context.TextureDescriptorGenerator.Get().GetEnumerable())
                        {
                            VRMShaders.TextureImporterConfigurator.Configure(textureInfo, context.TextureFactory.ExternalTextures);
                        }
                        var loaded = context.Load();
                        editor.SaveAsAsset(loaded);
                    }
            };

            using (var data = new GlbFileParser(vrmPath).Parse())
                using (var context = new VRMImporterContext(new VRMData(data)))
                {
                    var editor = new VRMEditorImporterContext(context, prefabPath);
                    // extract texture images
                    editor.ConvertAndExtractImages(onCompleted);
                }
        }
コード例 #24
0
        static void LoadFirstPerson(VRMImporterContext context)
        {
            var firstPerson = context.Root.AddComponent <VRMFirstPerson>();

            var gltfFirstPerson = context.VRM.extensions.VRM.firstPerson;

            if (gltfFirstPerson.firstPersonBone != -1)
            {
                firstPerson.FirstPersonBone   = context.Nodes[gltfFirstPerson.firstPersonBone];
                firstPerson.FirstPersonOffset = gltfFirstPerson.firstPersonBoneOffset;
            }
            else
            {
                // fallback
                firstPerson.SetDefault();
            }
            firstPerson.TraverseRenderers(context);

            // LookAt
            /*var lookAtHead =*/ context.Root.AddComponent <VRMLookAtHead>();

            switch (gltfFirstPerson.lookAtType)
            {
            case LookAtType.Bone:
            {
                var applyer = context.Root.AddComponent <VRMLookAtBoneApplyer>();
                applyer.HorizontalInner.Apply(gltfFirstPerson.lookAtHorizontalInner);
                applyer.HorizontalOuter.Apply(gltfFirstPerson.lookAtHorizontalOuter);
                applyer.VerticalDown.Apply(gltfFirstPerson.lookAtVerticalDown);
                applyer.VerticalUp.Apply(gltfFirstPerson.lookAtVerticalUp);
            }
            break;

            case LookAtType.BlendShape:
            {
                var applyer = context.Root.AddComponent <VRMLookAtBlendShapeApplyer>();
                applyer.Horizontal.Apply(gltfFirstPerson.lookAtHorizontalOuter);
                applyer.VerticalDown.Apply(gltfFirstPerson.lookAtVerticalDown);
                applyer.VerticalUp.Apply(gltfFirstPerson.lookAtVerticalUp);
            }
            break;
            }
        }
コード例 #25
0
        void OnLoaded(VRMImporterContext context)
        {
            var root = context.Root;

            root.transform.SetParent(transform, false);

            //メッシュを表示します
            context.ShowMeshes();

            // add motion
            var humanPoseTransfer = root.AddComponent <UniHumanoid.HumanPoseTransfer>();

            if (m_target != null)
            {
                GameObject.Destroy(m_target.gameObject);
            }
            m_target = humanPoseTransfer;
            SetupTarget();
        }
コード例 #26
0
        private static void LoadHumanoid(VRMImporterContext context)
        {
            context.AvatarDescription      = context.VRM.extensions.VRM.humanoid.ToDescription(context.Nodes);
            context.AvatarDescription.name = "AvatarDescription";
            context.HumanoidAvatar         = context.AvatarDescription.CreateAvatar(context.Root.transform);
            context.HumanoidAvatar.name    = Path.GetFileNameWithoutExtension(context.Path);

            var humanoid = context.Root.AddComponent <VRMHumanoidDescription>();

            humanoid.Avatar      = context.HumanoidAvatar;
            humanoid.Description = context.AvatarDescription;

            var animator = context.Root.GetComponent <Animator>();

            if (animator == null)
            {
                animator = context.Root.AddComponent <Animator>();
            }
            animator.avatar = context.HumanoidAvatar;
        }
コード例 #27
0
        static void LoadBlendShapeMaster(VRMImporterContext context)
        {
            context.BlendShapeAvatar      = ScriptableObject.CreateInstance <BlendShapeAvatar>();
            context.BlendShapeAvatar.name = "BlendShape";

            var blendShapeList = context.VRM.extensions.VRM.blendShapeMaster.blendShapeGroups;

            if (blendShapeList != null && blendShapeList.Count > 0)
            {
                foreach (var x in blendShapeList)
                {
                    context.BlendShapeAvatar.Clips.Add(LoadBlendShapeBind(context, x));
                }
            }

            var proxy = context.Root.AddComponent <VRMBlendShapeProxy>();

            context.BlendShapeAvatar.CreateDefaultPreset();
            proxy.BlendShapeAvatar = context.BlendShapeAvatar;
        }
コード例 #28
0
        static void LoadMeta(VRMImporterContext context)
        {
            var meta = context.ReadMeta();

            if (meta.Thumbnail == null)
            {
                /*
                 * // 作る
                 * var lookAt = context.Root.GetComponent<VRMLookAtHead>();
                 * var thumbnail = lookAt.CreateThumbnail();
                 * thumbnail.name = "thumbnail";
                 * meta.Thumbnail = thumbnail;
                 * context.Textures.Add(new TextureItem(thumbnail));
                 */
            }
            var _meta = context.Root.AddComponent <VRMMeta>();

            _meta.Meta   = meta;
            context.Meta = meta;
        }
コード例 #29
0
        public static Unit OnLoadModel(VRMImporterContext context)
        {
            LoadMeta(context);

            try
            {
                LoadHumanoidObsolete(context);
                Debug.LogWarning("LoadHumanoidObsolete");
            }
            catch (Exception)
            {
                LoadHumanoid(context);
            }

            LoadBlendShapeMaster(context);
            LoadSecondaryMotions(context);
            LoadFirstPerson(context);

            return(Unit.Default);
        }
コード例 #30
0
ファイル: VRMImporter.cs プロジェクト: karukaru808/UniVRM
        public static Unit OnLoadModel(VRMImporterContext context)
        {
            LoadMeta(context);

            try
            {
                LoadHumanoidObsolete(context);
                Debug.LogWarning("LoadHumanoidObsolete");
            }
            catch (Exception)
            {
                LoadHumanoid(context);
            }

            LoadBlendShapeMaster(context);
            VRMSpringUtility.LoadSecondary(context.Root.transform, context.Nodes,
                                           context.VRM.extensions.VRM.secondaryAnimation);
            LoadFirstPerson(context);

            return(Unit.Default);
        }