Unityでassimpnet-unityを使って外部fbxをランタイムでロードする

2025/01/23に公開

はじめに

OSSのデスクトップマスコット「uDesktopMascot」を開発しています。この中で 外部にあるfbxをロード機能を入れたいと思ったため、調査および実装方法を記載します。

https://github.com/MidraLab/uDesktopMascot

デモ

デモ1

Editor画面

モデルパス

注意

現時点では特定のfbxのみロードできます。すべてのfbxがロードできるわけではありません

開発環境

  • Unity 6000.0.31f1(IL2CPP)

事前調査

unityでfbxを外部からロードしようとすると以下あたりが見つかると思います(英語でもほぼ同様)

https://qiita.com/kazuki_kuriyama/items/e9b542ce7d895b53dcde

https://synamon.hatenablog.com/entry/unity_avatar_runtime_load

どこの記事でもだいたいABにするかTriLibを使ってロードするようになっています。今回はOSSのためアセットを含めることはできません。

ここで以下の記事にたどり着きました

https://blog.yucchiy.com/2021/01/assimp-for-model-loading-csharp/

こちらの記事では、AssimpNetというC#の3Dフォーマットのモデルをロードできると記載があります。

いろいろ調べこれは使えそうということで、関連ライブラリのまとめました

https://zenn.dev/ayousanz/scraps/8348fd381ee6cb

結論 Assimp for Unityが一番使いやすそうだったため、こちらを使って実装していきます。

インストール

以下の本家の記事を参考にインストールを行います

https://intelligide.github.io/assimp-unity/installation/

Package ManagerにRepositoryの追加を行います。

Package Manager Windowを開くと追加されているので、必要なものをインストールします。

fbxのロード処理

meshのロード

meshをロードするだけであれば以下で可能です

// Assimpのインポーターを作成
AssimpContext importer = new AssimpContext();

// シーンをインポート
Scene scene;
try
{
    scene = importer.ImportFile(fullPath, PostProcessPreset.TargetRealTimeMaximumQuality);
}
catch (Exception ex)
{
    Log.Error("[LoadFBX] モデルのインポート中にエラーが発生しました: {0}", ex.Message);
    return null;
}

ここにtextureの処理やshaderの処理を入れる必要があります。

shaderのロードと割り当て

適切なshaderを割り当てます。今回は Defaultは lilToonのcutoutにして、失敗した場合のフォールバックとしてURPのLit Shaderを割り当てます

Shader lilToon = Shader.Find("Hidden/lilToonCutout");
if (lilToon == null)
{
    Log.Error("[LoadFBX] MToon10 シェーダーが見つかりません。"
        + "UniVRM パッケージが正しくインポートされているか確認してください。");

    // フォールバックとして Standard シェーダーを使用
    lilToon = Shader.Find("Universal Render Pipeline/Lit");
}

UnityEngineMaterial material = new UnityEngineMaterial(lilToon);

textureの割り当て

textureは assimpMaterialのTextureDiffuseのパスを使って処理をします(ただこれだけだとうまくいかないモデルがあるので、汎用的に対応する必要はありそう)

// テクスチャ
if (assimpMaterial.HasTextureDiffuse)
{
    string texturePath = assimpMaterial.TextureDiffuse.FilePath;
    Log.Info("[LoadFBX] 取得したテクスチャパス: {0}", texturePath);

    // パスの区切り文字を統一
    texturePath = texturePath.Replace('\\', Path.DirectorySeparatorChar)
        .Replace('/', Path.DirectorySeparatorChar)
        .Trim();

    // テクスチャファイル名を取得
    string textureFileName = Path.GetFileName(texturePath);
    Log.Info("[LoadFBX] テクスチャファイル名: {0}", textureFileName);

    // テクスチャファイルを検索
    byte[] textureData = await FindAndLoadTextureAsync(textureFileName, fbxDirectory);

    if (textureData != null)
    {
        materialData.TextureData = textureData;
    }
    else
    {
        Log.Warning("[LoadFBX] テクスチャ '{0}' を見つけることができませんでした。", textureFileName);
    }
}

これらを行うことでfbxをロードしてテクスチャーの割り当ておよびShaderの割り当てを行うことができます

コードは以下にありますので、ご参照ください。

https://github.com/MidraLab/uDesktopMascot/blob/develop/Assets/uDesktopMascot/Scripts/Utility/LoadFBX.cs

MidraLab(ミドラボ)

Discussion