前提・実現したいこと
UnityのAR FoundationというARアプリ開発フレームワークを用いてアプリ制作に取り組んでおります。
現在やろうとしていることは、下記URLのサイトを参考に、自分で用意したVRMファイル(人型3Dモデル)を、アプリ上でカメラに映ったヒトの姿に合わせて表示させるARアプリの作成です。
URL: https://medium.com/tichise/arfoundationのhuman-body-trackingを使って-vrmフォーマットの骸骨を動かすサンプルを作った-5a9cd4410890
(ちなみに、僕はそこまで知識ある人ではないです、すみません。)
発生している問題・エラーメッセージ
以下のスクリプトのエラーメッセージが出てしまい、先に進めない状況になってしまってます。
エラーメッセージ↓
Assets/Scripts/VRMController.cs(55,10): error CS0246: The type or namespace name 'VRMHumanBodyTracker' could not be found (are you missing a using directive or an assembly reference?)
該当のソースコード
C#
1using System.Collections; 2using System.Collections.Generic; 3using System.IO; 4using UnityEngine; 5using UnityEngine.Networking; 6using VRM; 7//using UnityEngine.XR.ARFoundation.Samples; 8using UnityEngine.XR.ARFoundation; 9using UnityEngine.XR.ARSubsystems; 10//using Mathd; 11 12public class VRMController : MonoBehaviour 13{ 14 public Animator _vrmRootAnimator; 15 GameObject _vrmRoot; 16 17 private void Start() 18 { 19 // VRMをインポートして、非同期で読み込みます 20 ImportVRMAndLoadAsync(); 21 } 22 23 private void Update() 24 { 25 // VRMHumanBodyTrackerを取得 26 VRMHumanBodyTracker VRMHumanBodyTracker = GetVRMHumanBodyTracker(); 27 28 // VRMHumanBodyTrackerのoriginを取得 29 var humanBodyAnimator = VRMHumanBodyTracker._humanBodyAnimator; 30 31 // VRMHumanBodyTrackerからtrackableIdを取得。trackableIdはarHumanBodyManagerからtrackableIdを取得するのに使います 32 TrackableId trackableId = VRMHumanBodyTracker._trackableId; 33 34 if (_vrmRootAnimator == null) 35 { 36 Debug.Log("_vrmRootAnimator is null"); 37 return; 38 } 39 40 if (humanBodyAnimator == null) 41 { 42 Debug.Log("humanBodyAnimator is null"); 43 return; 44 } 45 46 47 // HumanoidのPoseをVRMに反映 48 UpdateVrmPose(humanBodyAnimator); 49 50 // humanBodyのposeを取得して、vrmのRootに状態を反映 51 UpdateVrmRootTransform(trackableId); 52 } 53 54 // VRMHumanBodyTrackerを取得 55 private VRMHumanBodyTracker GetVRMHumanBodyTracker() { 56 // Human Body TrackingをGameObjectとして取得 57 GameObject humanBodyTracking = GameObject.Find("Human Body Tracking"); 58 59 // Human Body Trackingに追加されてるcomponent VRMHumanBodyTrackerを取得 60 VRMHumanBodyTracker VRMHumanBodyTracker = humanBodyTracking.GetComponent<VRMHumanBodyTracker>(); 61 62 return VRMHumanBodyTracker; 63 } 64 65 // HumanoidのPoseをVRMに反映 66 private void UpdateVrmPose(Animator humanBodyAnimator) { 67 var originalHandler = new HumanPoseHandler(humanBodyAnimator.avatar, humanBodyAnimator.transform); 68 var targetHandler = new HumanPoseHandler(_vrmRootAnimator.avatar, _vrmRootAnimator.transform); 69 70 HumanPose humanPose = new HumanPose(); 71 originalHandler.GetHumanPose(ref humanPose); 72 targetHandler.SetHumanPose(ref humanPose); 73 } 74 75 // humanBodyのposeを取得して、vrmのRootにpositionとposeを反映 76 private void UpdateVrmRootTransform(TrackableId trackableId) { 77 GameObject arSessionOrigin = GameObject.Find("AR Session Origin"); 78 79 if (arSessionOrigin == null) { 80 Debug.Log(" arSessionOrigin is null"); 81 return; 82 } 83 84 // humanBodyの状態を管理するARHumanBodyManagerを呼び出す 85 ARHumanBodyManager arHumanBodyManager = arSessionOrigin.GetComponent<ARHumanBodyManager>(); 86 87 // trackableIdを使って、ARHumanBodyManagerからhumanBodyを取得 88 ARHumanBody humanBody = arHumanBodyManager.GetHumanBody(trackableId); 89 90 // humanBodyのposeを取得して、vrmのRootに状態を反映 91 _vrmRoot.transform.position = humanBody.pose.position; 92 _vrmRoot.transform.rotation = humanBody.pose.rotation; 93 94 Debug.LogFormat("pose:{0}", humanBody.pose.position); 95 } 96 97 // VRMをインポートして、非同期で読み込みます 98 private void ImportVRMAndLoadAsync() 99 { 100 // VRMファイルのパスを指定します 101 var vrmFilePath = $"{Application.StreamingAssetsPath}/BearSample.vrm"; 102 103 Debug.LogFormat("vrmFilePath:{0}", vrmFilePath); 104 105 // ファイルを読み込む 106 var bytes = File.ReadAllBytes(vrmFilePath); 107 108 // VRMImporterContextがVRMを読み込む機能を提供します 109 var vrmImporterContext = new VRMImporterContext(); 110 111 vrmImporterContext.ParseGlb(bytes); 112 113 // VRMのメタデータを取得 114 var meta = vrmImporterContext.ReadMeta(false); 115 116 // モデル名を出力します 117 Debug.LogFormat("VRM title:{0}", meta.Title); 118 119 // 非同期処理でVRMを読み込みます 120 vrmImporterContext.LoadAsync(_ => LoadVRM(vrmImporterContext)); 121 } 122 123 // VRMを読み込む 124 private void LoadVRM(VRMImporterContext vrmImporterContext) 125 { 126 // 読込が完了するとvrmImporterContextRootにモデルのGameObjectが入っています 127 _vrmRoot = vrmImporterContext.Root; 128 129 if (_vrmRoot == null) 130 { 131 Debug.Log("_vrmRoot is null"); 132 } 133 134 // VRMのAnimatorを取得 135 _vrmRootAnimator = _vrmRoot.GetComponent<Animator>(); 136 137 if (_vrmRootAnimator == null) 138 { 139 Debug.Log("_vrmRootAnimator is null"); 140 } 141 142 _vrmRoot.transform.position = new Vector3(0, 0, 0); 143 _vrmRoot.transform.rotation = Quaternion.Euler(0, 0, 0); 144 145 // ルートモーションを適用します 146 _vrmRootAnimator.applyRootMotion = true; 147 148 // メッシュを表示します 149 vrmImporterContext.ShowMeshes(); 150 151 Debug.Log("LoadVRM"); 152 } 153}
試したこと
まず、最初の2ヶ所の"using~~"をコメントにしてある部分は、そこでエラーが出てしまっていて、なくしても問題なさそうと思い省きました。
エラーメッセージ的に、「"VRMHumanBodyTracker"が見つからない」ということだと思うのですが、ここで見つけようとしているのが"VRMHumanBodyTracker"という名前のスクリプトなのであれば、上記のスクリプトと同じファイル内に"VRMHumanBodyTracker"という名前のスクリプトはあります。
ここで疑問に思ったことが2つありまして、まず「"VRMHumanBodyTracker"が見つからない」とのことですが、上記スクリプトの26行目の、Update()内の
VRMHumanBodyTracker VRMHumanBodyTracker = GetVRMHumanBodyTracker();
という部分は突っ込まれていない点です。ここでは取得ができているのでしょうか…?
また2つ目は、エラーメッセージで指摘されている部分は関数のようなものを定義している行だと思うので、別にそこで見つける必要があるのかな?と思ったりしました。
試したこととしては、"private"を"public"にしてみましたが変わらずダメでした。
補足情報(FW/ツールのバージョンなど)
Unity Version 2019.4.14f1
UniVRM-0.89.0_9470
あなたの回答
tips
プレビュー