simplestarの技術ブログ

目的を書いて、思想と試行、結果と考察、そして具体的な手段を記録します。

Unity:VRMの身長を測る

まえがき

VRM を動的ロードして、そんな VRM キャラクターとオンラインでコミュニケーションを取るロビーを制作中
キャラクターの頭のパーツを隠さずに、吹き出し位置を調整したいなと思ったとき

VRM の身長データの取得方法がわからなかったので調べてみて
わからなかったので、作り方を考えて、実際取得できることまで確認しました

動いたコードがこちら
全頂点座標の中から最も高い値をイベント引数で返すようにしてみました。

using UnityEngine;
using UnityEngine.Events;

public class VRMHeightMeasure : MonoBehaviour
{
    #region Scene Components
    [SerializeField] VRMLoaderGUI vrmLoaderGUI;
    #endregion

    internal UnityAction<GameObject /*vrmRoot*/, float /*isUserPlayerFlag*/> OnMeasureVRMHeight;

    void Start()
    {
        this.vrmLoaderGUI.OnLoadVRM += OnLoadVRM;
    }

    private void OnLoadVRM(GameObject vrmRoot, bool isPlayer)
    {
        float vrmHeight = 0;
        foreach (var meshRenderer in vrmRoot.GetComponentsInChildren<SkinnedMeshRenderer>())
        {
            if (null == meshRenderer.sharedMesh)
            {
                continue;
            }
            var meshHeight = meshRenderer.transform.position.y;
            foreach (var vertex in meshRenderer.sharedMesh.vertices)
            {
                if (vrmHeight < meshHeight + vertex.y)
                {
                    vrmHeight = meshHeight + vertex.y;
                }
            }
        }
        OnMeasureVRMHeight?.Invoke(vrmRoot, vrmHeight);
    }
}