#pragma warning disable 0414 using System; using System.IO; using System.Runtime.InteropServices; using UniGLTF; using UnityEngine; namespace VRM.Samples { public class VRMRuntimeLoader : MonoBehaviour { [SerializeField] bool m_loadAsync = default; [SerializeField, Header("GUI")] CanvasManager m_canvas = default; [SerializeField] LookTarget m_faceCamera = default; [SerializeField, Header("loader")] UniHumanoid.HumanPoseTransfer m_source; [SerializeField] UniHumanoid.HumanPoseTransfer m_target; [SerializeField, Header("runtime")] VRMFirstPerson m_firstPerson; VRMBlendShapeProxy m_blendShape; void SetupTarget() { if (m_target != null) { m_target.Source = m_source; m_target.SourceType = UniHumanoid.HumanPoseTransfer.HumanPoseTransferSourceType.HumanPoseTransfer; m_blendShape = m_target.GetComponent(); m_firstPerson = m_target.GetComponent(); var animator = m_target.GetComponent(); if (animator != null) { m_firstPerson.Setup(); if (m_faceCamera != null) { m_faceCamera.Target = animator.GetBoneTransform(HumanBodyBones.Head); } } } } private void Awake() { SetupTarget(); } private void Start() { if (m_canvas == null) { Debug.LogWarning("no canvas"); return; } m_canvas.LoadVRMButton.onClick.AddListener(LoadVRMClicked); m_canvas.LoadBVHButton.onClick.AddListener(LoadBVHClicked); } async void LoadVRMClicked() { #if UNITY_STANDALONE_WIN var path = FileDialogForWindows.FileDialog("open VRM", ".vrm"); #elif UNITY_EDITOR var path = UnityEditor.EditorUtility.OpenFilePanel("Open VRM", "", "vrm"); #else var path = Application.dataPath + "/default.vrm"; #endif if (string.IsNullOrEmpty(path)) { return; } var bytes = File.ReadAllBytes(path); // なんらかの方法でByte列を得た var context = new VRMImporterContext(); // GLB形式でJSONを取得しParseします context.ParseGlb(bytes); // metaを取得(todo: thumbnailテクスチャのロード) var meta = await context.ReadMetaAsync(); Debug.LogFormat("meta: title:{0}", meta.Title); // ParseしたJSONをシーンオブジェクトに変換していく if (m_loadAsync) { LoadAsync(context); } else { context.Load(); OnLoaded(context); } } /// /// メタが不要な場合のローダー /// void LoadVRMClicked_without_meta() { #if UNITY_STANDALONE_WIN var path = FileDialogForWindows.FileDialog("open VRM", ".vrm"); #elif UNITY_EDITOR var path = UnityEditor.EditorUtility.OpenFilePanel("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 } 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 } void LoadBVHClicked() { #if UNITY_STANDALONE_WIN var path = FileDialogForWindows.FileDialog("open BVH", ".bvh"); if (!string.IsNullOrEmpty(path)) { LoadBvh(path); } #elif UNITY_EDITOR var path = UnityEditor.EditorUtility.OpenFilePanel("Open BVH", "", "bvh"); if (!string.IsNullOrEmpty(path)) { LoadBvh(path); } #else LoadBvh(Application.dataPath + "/default.bvh"); #endif } void OnLoaded(VRMImporterContext context) { var root = context.Root; root.transform.SetParent(transform, false); //メッシュを表示します context.ShowMeshes(); // add motion var humanPoseTransfer = root.AddComponent(); if (m_target != null) { GameObject.Destroy(m_target.gameObject); } m_target = humanPoseTransfer; SetupTarget(); } void LoadBvh(string path) { Debug.LogFormat("ImportBvh: {0}", path); var context = new UniHumanoid.BvhImporterContext(); context.Parse(path); context.Load(); if (m_source != null) { GameObject.Destroy(m_source.gameObject); } m_source = context.Root.GetComponent(); SetupTarget(); } } }