MRが楽しい

MRやVRについて学習したことを書き残す

ヒューマノイドアバターのボーン構造を取得でき……なかった

おいかけっこアプリの修正兼、技術調査枠です。

モデルとコンポーネントの切り分けによってモデルの差し替えが容易になったおいかけっこアプリですが。
まだ一点、モデルの取り込み後、視線追従コンポーネントに以下の設定を行う作業があります。
f:id:bluebirdofoz:20170619003119j:plain

これも自動化できないかと思い、調査してみました。
ヒューマノイドアバターにはHumanDescriptionという設定が行われており、ここでオブジェクトと共通化された関節名とのマッピングが行われています。
japan.unity3d.com
docs.unity3d.com

つまり、このマッピングを動的に取得できれば、モデルの首や頭がどのゲームオブジェクトであるか分かるという事です。
意気揚々と色々調べてみましたが。。

既に生成されたアバターからhumanDescriptionを取り出す方法が見つかりませんでした。
docs.unity3d.com

そもそも動的にアバターを変更することが推奨されていないので、あえて隠蔽されているのかもしれません。
docs.unity3d.com

すると動的にモデルを差し替えるには、アバターは変えずにメッシュやボーンの方を差し替えるべきということでしょうか。
MMDモデルに限定すれば、これは実現可能ですが、流石にユニティちゃんとMMDモデルの差し替えでこれをやるのはかなりの労力が必要です。

ただ今回はアバターに変更を加えたい訳ではなく、首と頭のオブジェクト参照が欲しいだけなので強引に取得プログラムを組んでみました。
・BoneCollector.cs

  /// <summary>
  /// ヘッドボーンオブジェクトの取得
  /// </summary>
  /// <returns>ヘッドボーンオブジェクト</returns>
  private GameObject GetHeadBoneName()
  {
      GameObject boneObject = null;

      // モデル配下のトランスフォームを再帰的に取得
      Transform[] transformArray = p_ModelObject.GetComponentsInChildren<Transform>();

      Transform boneTransform = null;
      // ユニティちゃんモデルの場合
      if (boneTransform == null)
      {
        foreach(Transform child in transformArray)
        {
          if (child.name == "Character1_Head")
          {
            boneTransform = child;
          }
        }
      }
      // MMDモデルの場合
      if (boneTransform == null)
      {
        foreach (Transform child in transformArray)
        {
          if (child.name == "頭")
          {
            boneTransform = child;
          }
        }
      }

      // ゲームオブジェクトを取得
      if (boneTransform != null)
      {
        boneObject = boneTransform.gameObject;
      }

      return boneObject;
  }

名前を決め打ちでオブジェクトを取得します。
アバターからマッピングが取れれば、決め打ちする必要はないのですが……今後の課題です。

これにより、モデルの差し替えが非常に楽になりました。
f:id:bluebirdofoz:20170619003233j:plain
unitychanオブジェクトと同じ階層に、MMDモデルの変換オブジェクトを投入します。
f:id:bluebirdofoz:20170619003252j:plain
モデルマネージャのターゲットオブジェクトを差し替えるだけで……。
f:id:bluebirdofoz:20170619003346j:plain
見事、MMDモデルがゲームの操作キャラクタになりました。
うむ、簡単。これなら前回調査したAssetBundleと組み合わせての読み込み実行も難しくないかも。

ボーンの自動取得も正常に動作し、ちゃんと視線追従もしてくれています。
f:id:bluebirdofoz:20170619003424j:plain
ボイスコントローラも切り分けたので、MMDモデル用の音声コントローラオブジェクトを用意すれば、同じ要領で声の差し替えも可能です。