bDoFastBuild が意図せず有効になったメッシュのデータ不整合について

お世話になっております。

以下のスレッドにあります

[Content removed]

bDoFastBuild が意図せず有効になったメッシュの Bounds が破損する問題について、弊社でも類似の症状が発生しました。

状況を検証したところ、以下の2点がわかりました。

・上記のスレッド内では、メッシュの bDoFastBuild が有効になる原因は不明のようでしたが、PIE 中に Static Mesh を再インポートすることで、該当メッシュの bDoFastBuild が有効になることを確認しました。

・bDoFastBuild が有効になったメッシュに対して、エディタ上で UV チャンネルの操作を行ったところ、UV チャンネルが逆に増加し、それらが削除不能になる問題が発生することを確認しました。

再現手順の項目には、上記の検証結果をミニマムで再現可能な手順を記載しております。

ここまでの内容を踏まえて、以下の点を相談させてください。

・PIE 中に Static Mesh を再インポートすることで該当メッシュの bDoFastBuild が有効になる点は不具合に当たるかと存じますが、取り急ぎプログラム上で回避する手段 ( PIE 中のインポートを防ぐ, bDoFastBuild を True にしないようにするなど ) があればご案内頂けますと幸いです。

・UV チャンネルの不整合を起こしたアセットについて、bDoFastBuild を無効にした上で再インポートしても改善が見られませんでした。この状態のアセットを修復する方法はありますでしょうか。

以上、お手数ですが、ご確認頂けますと幸いです。

[Attachment Removed]

再現手順
1. バニラの UE 5.7.4 を起動し、ブランクの新規プロジェクトを作成する

2. /Engine/BasicShapes/Plane をプロジェクトのコンテンツフォルダにコピーする

3. 2. のアセットについて、アセットアクションから FBX をエクスポートする

4. PIE を実行する

5. PIE 中に、3. でエクスポートした FBX で 2. のアセットを再インポートする

→ 再インポート後のアセットに bDoFastBuild=True が追加されることを確認する

→ 再インポート後のアセットの UV チャンネルが 7 まで増加し、“選択項目を削除” が実行できないことを確認する

[Attachment Removed]

その他、確認した関連スレッドは以下の通りです:

[Content removed]

[Content removed]

[Attachment Removed]

お世話になっております。

ソースを確認したところ、原因は Interchange 側にありました。

UInterchangeStaticMeshFactory は PIE 中もランタイムインポートと判定してしまい、その経路で bDoFastBuild が true になります。この経路ではメッシュのビルドが簡略化されるため、Bounds や Nanite が正しく生成されません。

もう一点、bDoFastBuild は DDC キーに含まれていません。そのため false に戻して再インポートしても、同じソースなら DDC から壊れたデータが返ってきます。再インポートで直らなかったのはこのためです。

PIE 中の再インポートでこうなる点は不具合として社内に報告します。参考までに、再インポート時に bDoFastBuild をリセットする修正が UE-383625 として登録されています。

回避策ですが、PIE 中は StaticMesh のインポート自体を止めるのが一番簡単です。エンジンの変更は不要です。

FEditorDelegates::PostPIEStarted.AddLambda({ IAssetTools::Get().GetAssetClassPathPermissionList(EAssetClassAction::ImportAsset)->AddDenyListItem(TEXT(“NoSMImportInPIE”), UStaticMesh::StaticClass()->GetPathName()); });

FEditorDelegates::EndPIE.AddLambda({ IAssetTools::Get().GetAssetClassPathPermissionList(EAssetClassAction::ImportAsset)->UnregisterOwner(TEXT(“NoSMImportInPIE”)); });

エンジン側で直す場合は、InterchangeStaticMeshFactory.cpp の BeginImportAsset_GameThread で bIsAppGame を設定した直後にこれを追加してください。

if (Arguments.ReimportObject) { ImportAssetObjectData.bIsAppGame = false; }

壊れたアセットの修復は、bDoFastBuild を false にしたあと CommitMeshDescription をデフォルト引数で呼んでください。GUID が新しくなるので DDC キーも変わります。

Mesh->Modify();

Mesh->bDoFastBuild = false;

for (int32 Lod = 0; Lod < Mesh->GetNumSourceModels(); ++Lod)

{

if (Mesh->IsMeshDescriptionValid(Lod)) { Mesh->GetMeshDescription(Lod); Mesh->CommitMeshDescription(Lod); }

}

Mesh->Build();

そのあと保存して、PIE を止めた状態で一度通常の再インポートをしてください。UV チャンネルの件も、これで直るか確認していただけると助かります。直らなければ再現手順をもとに調べます。

お手数ですが、よろしくお願いいたします。

[Attachment Removed]

ご返信ありがとうございます。

ご案内頂きました以下の2点を確認いたしました。

1. PIE 中のインポートの拒否

ご案内頂きました以下のコードを使用しました。

FEditorDelegates::PostPIEStarted.AddLambda({ IAssetTools::Get().GetAssetClassPathPermissionList(EAssetClassAction::ImportAsset)->AddDenyListItem(TEXT("NoSMImportInPIE"), UStaticMesh::StaticClass()->GetPathName()); });
 
FEditorDelegates::EndPIE.AddLambda({ IAssetTools::Get().GetAssetClassPathPermissionList(EAssetClassAction::ImportAsset)->UnregisterOwner(TEXT("NoSMImportInPIE")); });

結果として、インポートの拒否は実現できました。

ただし、インポートするメッシュごとに以下の差が見られました。

・“インポートできませんでした” と、インポートに失敗したことが確認できるダイアログが表示されるケース

・“インポート完了” と、まるでインポートが成功したかのようにダイアログが表示されるケース

※ 後者においてもメッシュに変更は生じなかったので、インポートの拒否自体は正しく動作しているものと思われます。

念のためデバッグしつつコードを確認したところ

Engine\Source\Runtime\Interchange\Engine\Private\InterchangeManager.cpp

の void UInterchangeManager::ReleaseAsyncHelper( ) 関数内の Results に UInterchangeResultTextureDisplay_TextureFileDoNotExist のインスタンスが含まれており、これが UInterchangeResultSuccess を継承しているため、EInterchangeResultType::Success を返し、成功扱いになっておりました。

インポートの拒否自体は動作しているようだったので、大きな問題では無いですが、念のため報告させて頂きます。

2. 壊れたアセットの修復

ご案内頂きました以下のコードを当てた該当アセットを再インポートしましたが、UV は直らず、変わらず UV チャンネルの削除もできませんでした。

Mesh->Modify();
 
Mesh->bDoFastBuild = false;
 
for (int32 Lod = 0; Lod < Mesh->GetNumSourceModels(); ++Lod)
 
{
 
if (Mesh->IsMeshDescriptionValid(Lod)) { Mesh->GetMeshDescription(Lod); Mesh->CommitMeshDescription(Lod); }
 
}
 
Mesh->Build();

しかしながら、以前ご案内した再現手順で用意した Plane や、別途新規にインポートし、意図的に破損させたアセットでは、再インポートで改善することを確認いたしました。

よって、再現手順での調査は厳しいかもしれません。

該当のアセットは、新規アセットとしてのインポートで改善可能なので、修復方法のご案内は現時点では必須ではございません。

以上、よろしくお願いいたします。

[Attachment Removed]

お世話になっております。

UInterchangeResultTextureDisplay_TextureFileDoNotExist は UInterchangeResultDisplay_Generic 経由で UInterchangeResultSuccess を継承しているため、表示用のメッセージが一つでもあると成功扱いになります。拒否自体は正しく動いていますので、表示の問題として社内に伝えておきます。PIE 中の再インポートの件も社内で対応を進めています。

修復の件も承知しました。Plane や新しく壊したアセットでは直るとのことなので、該当アセットには保存済みのソースデータ側に再現手順では出ない別の不整合が残っていると思われます。新規インポートで対応できるとのことですので、こちらは一旦クローズとさせてください。

もし原因を追いたい場合は、該当アセットを共有いただければこちらで中身を確認します。

引き続きよろしくお願いいたします。

[Attachment Removed]

お世話になっております。

​

現状に対するご連絡、ありがとうございます。承知いたしました。​

​

当初の問題は概ね解決いたしましたので、​本チケットはいったんクローズで問題ございません。

この度はご対応誠にありがとうございました。

​

以上です。今後ともよろしくお願いいたします。​

[Attachment Removed]