Synamon’s Engineer blog

Synamonはリアルとデジタルの融合を加速させるため、メタバース領域で法人向けにサービス提供を行うテックカンパニーです。現在開発を進めている「メタバース総合プラットフォーム」をはじめ、メタバース市場の発展に向けた事業展開を行っています。このブログでは、メタバース技術とその周辺の技術、開発全般に関してエンジニアがお話しします。

Unityでアバターを外部からいい感じにロードしたい

こんにちは、エンジニアリングマネージャーの渡辺(@mochi_neko_7)です。

私の前回の記事では、Unityにおける画像のランタイムでのロード方法を紹介しました。

synamon.hatenablog.com

Unityは画像に限らずRuntimeで外部リソースを取り込もうとするとひと手間必要になりますよね。

今回は、3DモデルをRuntimeでHumanoidとしてロードしアバターとして利用できるようにしたい、というお話になります。

Clusterをはじめ最近のメタバース系サービスでは、ユーザーが持っているアバターをアップロードして利用できるというのも一般的になりつつあると思います。

その場合には当然ユーザーのアバターのデータはアプリ本体に含めることはできないため、Runtimeで外部から読み込んで利用することになります。

VRChatのようにAssetBundle × 独自のSDKを組むという手法もありますが、開発するにも利用するにも難易度が高いため、一般向けに提供するには少しハードルが高いです。

一方、アバター用の3DモデルフォーマットであるVRMや汎用3DモデルフォーマットのFBX、glTFなどを利用するとアバターの再利用性も良いですし、 開発する観点でも容易になるため、アバターをこれらのフォーマットのバイナリーファイルとしてRuntimeで読み込む手法が取られることが多いと思います。

ただしアバターとして利用するためにはただ3Dモデルを読み込むだけでは不十分で、ユーザーの操作に応じたアニメーションができるようにセットアップしてあげる必要があります。

本記事では、外部からアバターの3Dモデルのファイルを取り込みアバターとしてHumanoid Boneによるアニメーションができる状態にすることをゴールに、 基本的な流れや利用できるライブラリ、フォーマット別の注意点などを紹介します。

全体の処理の流れ

想定される基本的な処理の流れは以下になります。

  1. アバターに使用したい3Dモデルのファイルをバイナリーデータとして読み込む
  2. フォーマット別にデコードする
  3. HumanoidとしてセットアップされたGameObjectにする
  4. Boneを使ったHumanoidアニメーションでアバターが動かせるようになる

1では具体的にどこからデータを読み込むのかは問いません。

ローカルストレージやStreamingAssetsに入れてもいいですし、URLで取得しても構いませんし、テキストデータとしてAddressableにしても大丈夫です*1

最終的には byte[]Stream の形で取得する形になるでしょう。

2ではファイルフォーマット毎にデコード方法が異なりますが、Unityは標準ではRuntimeでの3Dモデルファイルの読み込みには対応していないため、各フォーマットに対応したライブラリを使用することになります。

対応するフォーマットの種類に関してはサービスの方針次第ではありますが、本記事ではアバターに使用することを想定しているVRM、海外でも比較的広く使われている汎用フォーマットであるglTFFBXの3つを紹介します。

3ではUnityのAvatarというHumanoidアニメーションが手軽にできる仕組みに乗せることで、4のBoneを使ったHumanoidアニメーションができるようにセットアップします。

docs.unity3d.com

4はHumanoidアニメーションで実際に動かす部分ですが、Animator Controller を使ってアニメーションをさせたり、あるいはIK(Inverse Kinematics)を使ってインタラクティブに動かすなどサービスによってさまざまな手法が取れます。

アバターとして利用するためには、3Dモデルを読み込むだけではなく、それをアニメーションさせるためのセットアップが必要になるのがポイントです。

サービス仕様によって異なる部分の大きい1と4は他の記事でも紹介があると思いますので省略させていただき、2と3のステップに関してフォーマット別に詳しく紹介します。

VRM

vrm-consortium.org

「VRM」はVRアプリケーション向けの人型3Dアバター(3Dモデル)データを扱うためのファイルフォーマットです。

拡張子は .vrm で、Unity向けのプラグインも提供されています。

github.com

VRMは説明にもあるように人型(Humanoid)であることを前提に設計されており、更にVRで使用するために必要な基本仕様を備えています。

ですので基本的には2~3の流れをフォーマットの仕様としてライブラリ側で行ってくれるため、難しく考えることなくアバターとして使用できます。

2のバイナリーデータのRuntimeでのロードにも対応していますし、4は生成されたPrefab(GameObject)にアタッチされている Animator などを用いれば実現できるでしょう。

ライブラリの使い方はバージョンによってAPI仕様が少し異なるため、公式のドキュメントを参照してください。

vrm-c.github.io

VRMを採用する上で注意すべきこと

VRMを採用する際には二つ注意点があります。

一つはVRMがまだ日本内での使用が主で、海外ではまだ普及していない点です。

VRMコンソーシアムの動きもありますし、海外での他のフォーマットの使用例もあまり聞かないため今後に期待したいですね。

prtimes.jp

とはいえ国内ではVroidをはじめ製作・利用のプラットフォームも出てきているため、サービスのターゲット次第ではVRMのみ対応しても十分な場合もあるでしょう。

vroid.com

二つ目が、標準ではUnityのURPに対応していない点です。

MetaQuest2を含むモバイル環境ではグラフィックの負荷軽減は可能な限り行いたいため、URPを採用したいケースも多いと思います。

VRMで使用可能なTool ShaderはMToonというものなのですが、これが通常のRender Pipeline前提で作られているものになっています。

一応自前で拡張可能なAPIも用意されているのですが、Shaderの仕様を理解したうえで拡張する必要があるため少しハードルが高いです。

vrm-c.github.io

それに近いことをされているのは調べるといくつか出てきますので、参考になるかと思います。

github.com

VRMの発起人であるVirtual CastがURP対応をするという発表もあったため、少し待てば正式に対応があるかもしれません。

Humanoidとしてのセットアップを仕様としてしてくれる以外にも、詳細なメタデータ、LipSyncの定義など開発者目線では総じて扱いやすいフォーマットではあるため、コメントした二点を除けばVRM対応はそれほど苦戦することはないかと思います。

glTF

www.khronos.org

glTF™ is a royalty-free specification for the efficient transmission and loading of 3D scenes and models by engines and applications. glTF minimizes the size of 3D assets, and the runtime processing needed to unpack and use them. glTF defines an extensible, publishing format that streamlines authoring workflows and interactive services by enabling the interoperable use of 3D content across the industry.

3Dモデルの標準規格として作成されているglTFはJsonベースの汎用フォーマットで、Runtimeで使用することを想定しています。

Json形式の拡張子は .gltf、バイナリー形式の拡張子は .glbです。

あくまで汎用フォーマットであるのでHumanoidの考慮やアバター向けの規格はなく、3のHumanoidとしてのセットアップをちゃんと対応する必要があります。

ちなみに先に紹介したVRMはglTF(2.0)をベースに拡張したもので、glTFの拡張可能な領域にアバター向けの規格を入れているという形になります。

Ready Player Meをはじめ海外のアバター系サービスではglTFの出力に対応しているものも多く、日本以外のユーザー向けにサービスを提供することを想定している場合はVRM以外のフォーマットも候補になるでしょう。

readyplayer.me

NTF系のサービスもVRMかglTFのどちらかが多い印象です。

Unity向けのglTFライブラリはいくつかあります。

github.com

github.com

UniGLFTはUniVRMにも組み込まれています。

ライブラリを選定する上で気にすべき観点は以下になります。

  • Runtimeでの読み込みに対応しているか?(非同期のAPIがあるのがベスト)
  • URPなどに対応しているか?(使用しない場合は気にしないでOK)
  • Humanoidのセットアップができるか?

URPの対応はglTFだと基本的には Standard Shader → Universal Render Pipeline/Lit Shaderの変換なので難しくないでしょう。

しかし今回のアバター用途では特に3つ目の対応を自前で行うのは大変になります。

通常Unityで事前に3Dモデルをアセットとして読み込む場合には、Editor上でAvatarのセットアップをすることができます。

docs.unity3d.com

しかしこの機能はEditor上でしか利用できないため、Runtimeではこれに相当する作業をスクリプト上でする必要があります。

ですのでここの処理を自前で頑張ってやることを覚悟していたのですが、実はTriLibという様々な3Dモデルをロードできるアセットを使うと、Boneの命名規則の設定をするだけでセットアップをすることができます。

https://assetstore.unity.com/packages/tools/modeling/trilib-2-model-loading-package-157548?locale=ja-JP

おまけにURPにも対応しているので、有料ではありますがTriLibを買ってしまえばそれほど苦労することなくglTFファイルをアバターとして利用できます。

TriLibでのHumanoidのセットアップ方法

TriLibを使う場合のHumanoid向けのセットアップ方法も簡単にですが紹介しておきます。

3Dモデルのファイルをロードする際に、AssetLoaderOptions という ScriptableObject を指定することで、ロード時の処理の細かなカスタマイズをすることができます。

その設定項目の中でHumanoid向けの設定のみ紹介します。

  • Rig > Animation TypeHumanoid に設定する
  • Rig > Avatar Definition は任意
    • Create From This Model にすると、下記のMapperを使って動的に Avatar を生成します
    • Copy From Other Avatar にすると、既に作成済みの Avatar を利用することができます
  • Rig > Humanoid Avatar Mapper を指定する
    • Avatar のHumanoid Boneの設定方法を指定できます
  • Rig > Root Bone Mapper を指定する
    • 3DモデルのTransformの中から、BoneのRootとなるオブジェクトの検索方法を指定できます

Humanoid Avatar Mapperというのが重要で、AvatarのEditor上でのセットアップに相当する操作を、Humanoid Boneと3DモデルのBoneのMappingを、Boneの名前の規則性をベースに自動で行うことができるようになっています。

ただしこれは使用する3DモデルのBoneの作り方に依存する部分もあるため、調整が必要になる場面もあるでしょう。

とはいえ下2つのMapperはサンプルも用意されていて、それらを使えば基本的には問題なくロードできるため、それほど難易度は高くありません。

  • Humanoid Avatar Mapper
    • By Name Humanoid Avatar Mapper
    • Mixamo And Biped By Name Humanoid Avatar Mapper(おすすめ)
  • Root Bone Mapper
    • By Name Root Bone Mapper
    • By Bones Root Bone Mapper

これらは Create > TriLib > Mappers > Humanoid / Bone から ScriptableObject のインスタンスを簡単に作成できます。

Humanoidのセットアップに成功すると、ロード後に生成される GameObject にアタッチされている AnimatorAvatar がセットされており、この Animator を使用してアニメーションさせることができます。

TriLibでのURPの使用方法

TriLibのMaterialの生成時にURPを使用する方法は、上記の Asset Loader Options で設定できます。

Materials > Material MappersUniversalPRMaterialMapperScriptableObject のインスタンスを指定してください。

FBX

www.autodesk.com

Adaptable file format for 3D animation software FBX® data exchange technology is a 3D asset exchange format that facilitates higher-fidelity data exchange between 3ds Max, Maya, MotionBuilder, Mudbox and other propriety and third-party software.

拡張子は .fbx ですが、ASCII形式とバイナリー形式があります。

FBXはAutodesk社の策定しているフォーマットですが、同じくAutodesk社が開発しているMayaや3ds Maxなどの3Dモデリングソフトのシェアが高いこともあり、FBXは広く使われているフォーマットです。

glTFと同じく汎用3Dフォーマットのため、Humanoidとしてのセットアップが別途必要になります。

UnityはFBXのEditorでのロードは対応していますがRuntimeでのロードには対応していないため、やはりライブラリを使用することになります。

FBXをインポートできるライブラリも調べるといくつか出てきますが、glTFのところで紹介したTriLibがFBXにも対応しているためTriLibを使うのがおすすめです。

Humanoidのセットアップ方法やURPの対応方法もまったく同じですので、glTFの欄を参照してください。

おわりに

以上の紹介した内容で、

  • VRM
  • glTF
  • FBX

の3つのフォーマットの3Dモデルファイルを、

  • UniVRM
  • TriLib

の2つのライブラリを使い分けることで、Runtimeで3Dモデルをロードし、HumanoidとしてセットアップすることでHumanoid Boneによるアニメーションができる状態にすることができます。

ライブラリの使い分けが少し手間な部分ではありますが、ファイルのbyte[] or Stream から最終的にHumanoidとしてセットアップした GameObject を作成して Animator でアニメーションできる、という入出力の形式は共通のため、仕組みを作ってしまえば広いフォーマットに対応したアバター読み込み機能が作れます。

実際にはこれ以外にもファイルのリソース管理やキャッシュ、URP対応のToonShaderのカスタマイズ、アニメーションのさせ方やIKの調整、マルチプレイでのネットワーク同期、パフォーマンス調整などなど、アバターをアプリケーションに組み込むためには考えるべきことがたくさんあると思います。

とはいえ基本的なところは今回の範囲で抑えられると思いますので、アバターをRuntimeで外部からロードして使用したい方の参考になれば幸いです。

*アイキャッチのVRMはVroid HumのAvatar_Sample_Aを使用させていただきました。

hub.vroid.com

*1:拡張子を無理やり.txtにしてTextAssetとしてロードし、TextAsset.bytesでバイナリーデータを引っこ抜く、という裏技が一応あります