これは ここのえ Advent Calendar 2023 Day 4 の記事です。
Overview
UnityでVRMを使用し、各種外部APIやデバイスを使ってモデルを動かしたい事、ありますよね……?
予めインスペクタ上に配置したモデルであれば、対象となるボーンの参照をSerializeField等で捕まえておけばいいので簡単ですが、ランタイムロードしたモデルとなると少し話が変わってきます。
VRMのパッケージに付属している、VRMUtility
を使ってランタイムロードした際、特定のボーンを取得することができます。
実装
// ランタイムロード
var path = "/path/to/vrm"
var instance = await VrmUtility.LoadAsync(path, new RuntimeOnlyAwaitCaller());
instance.ShowMeshes();
// アバターのGameObjectにHumanoid classをアタッチ
var avatar = instance.gameObject;
var humanoid = avatar.AddComponent<Humanoid>();
humanoid.AssignBonesFromAnimator();
// ボーンの参照を取得
var neck = humanoid.Neck;
var spine = humanoid.Spine;
VRM 0.x系で動作確認しています。
解説
ランタイムロードについては結構情報があるので、ここでは説明は省略します。
var instance = await VrmUtility.LoadAsync(path, new RuntimeOnlyAwaitCaller());
var avatar = instance.gameObject;
まずロード時の返り値ですが、RuntimeGltfInstance
が返ってきます。
RuntimeGltfInstance
はMonoBehavior
を継承しているため、正常にVRMデータがロードできているならば、avatar.gameObject
でGameObjectの参照を引っ張ってくることができます。
var humanoid = avatar.AddComponent<Humanoid>();
humanoid.AssignBonesFromAnimator();
今回の中心的な部分はこのコードになるのですが、VRMのパッケージ内にHumanoid
コンポーネントが用意されています。
これはgltfで読み込んだモデルにヒューマノイドボーンが設定されていれば、シーンから直接Humanoid Avatarを作ることができます。
ここで用意されているメソッド AssignBonesFromAnimator()
を呼び出すと、自動的にボーンの構成を読み込んでくれます。
またHumanoid
コンポーネントで各種ボーンの参照を保持しているので、これを引っ張ってくることで、ランタイムロードされたモデルのボーン参照を取ってくることができます。
おまけ
JINS MEMEを使って3Dモデルを動かす、VTuber向け配信用アプリケーション「Streameme」を開発しています。それの開発時に得た知見でした。
参考資料