お世話になっております。
決定的 Cook / Package の検証中、WorldPartition map の Cooked 出力が揺れるケースを確認したためご相談させてください。
DiffOnly Cook ログでは以下の差分として検出されています。
Serialized Property:
StructProperty /Script/Engine.RuntimePartition:DebugColor
調査したところ、直接見えている差分は DebugColor ですが、根本原因は UWorldPartitionRuntimeHashSet::FixupHLODSetup 内で生成される URuntimePartitionPersistent の UObject 名が安定していないことに見えます。
該当箇所では、明示的な HLOD Layer Partition Assignation が有効な場合に以下で生成されています。
NewObject<URuntimePartitionPersistent>(this, NAME_None)
このため UObject の自動命名により RuntimePartitionPersistent_0 / RuntimePartitionPersistent_1 のような suffix が付きますが、Cook ごとの生成順の違いで suffix が揺れる可能性があります。また URuntimePartition::SetDefaultValues() では DebugColor が GetName() を seed に初期化されるため、UObject 名が揺れると DebugColor も変わります。
DebugColor は名前としては debug 用に見えますが、URuntimePartition::DebugColor は WITH_EDITORONLY_DATA 外の通常 UPROPERTY で、FRuntimePartitionHLODSetup::PartitionLayer も WITH_EDITORONLY_DATA 外の Instanced UPROPERTY です。そのため Development / Shipping を問わず Cooked data 側に入る差分という認識です。また DebugColor 以前に、UObject 名自体も ExportMap / serialized object 側で揺れるように見えます。
対策として、NAME_None ではなく RuntimePartitions 配列 index など同一 content で安定する値から object name を明示生成することを検討しています。
質問:
類似事例として、NiagaraDataInterface の MultiProcess Cook で、Cook 中に生成される UObject に deterministic name を付ける対応が検討されている記事を確認しました。
[Content removed]
今回の WorldPartition RuntimeHashSet の URuntimePartitionPersistent も、同様に deterministic name を付けるべきケースと考えてよいでしょうか?
また、本件について、以降のバージョンで修正予定、または既に修正済みの CL があれば教えてください。
お世話になっております。
ご報告ありがとうございます。調査を行いましたところ、ご認識の通り UWorldPartitionRuntimeHashSet::FixupHLODSetup() 内で NewObject<URuntimePartitionPersistent>(this, NAME_None) により UObject 名が自動 suffix 付きになり、Cook 実行ごとに生成順の差で名前が非決定論的差分が発生する可能性があります。修正方針として、Niagara DataInterface の MultiProcess Cook 事例と同様、Cook 時に生成される Instanced Subobject には content 由来の決定的な名前を付けるべきケースと同じ考え方で問題ございません。最終的には、以下のような変更を想定しております。こちらは既知の問題として社内では認識していない問題となっており、新規の問題としてデータベースに登録し、根本的な修正を行う予定です。ご不便をお掛けしまして恐れ入りますが、どうぞよろしくお願いいたします。
Source/Runtime/Engine/Private/WorldPartition/RuntimeHashSet/WorldPartitionRuntimeHashSet.cpp : FixupHLODSetup()
//修正前:
if (IWorldPartitionEditorModule::Get().GetRequireExplicitHLODLayerPartitionAssignation())
{
FRuntimePartitionHLODSetup& PersistentHLODSetup = RuntimePartition.HLODSetups.Emplace_GetRef();
PersistentHLODSetup.PartitionLayer = NewObject<URuntimePartitionPersistent>(this, NAME_None);
// ...
}
//----------------------------------------------------
//修正後:
if (IWorldPartitionEditorModule::Get().GetRequireExplicitHLODLayerPartitionAssignation())
{
const FName PersistentPartitionName(*FString::Printf(
TEXT("RuntimePartitionPersistent_%s"),
*RuntimePartition.Name.ToString()));
FRuntimePartitionHLODSetup& PersistentHLODSetup = RuntimePartition.HLODSetups.Emplace_GetRef();
PersistentHLODSetup.PartitionLayer = NewObject<URuntimePartitionPersistent>(this, PersistentPartitionName);
// ...
}
お世話になっております。
ご確認および詳細なご回答ありがとうございます。
本件について、UWorldPartitionRuntimeHashSet::FixupHLODSetup() 内で生成される URuntimePartitionPersistent に対して、content 由来の決定的な UObject 名を付ける方針で問題ない旨、承知いたしました。
また、既知問題ではなく新規問題として登録し、根本修正を行う予定とのこと、承知いたしました。
ご提示いただいた修正方針を参考に、こちらでも確認を進めます。
ご対応いただきありがとうございました。
こちらの問題は以下の番号でデータベースに登録させて頂きました。2-3営業日後に公開される予定です。
https://issues.unrealengine.com/issue/UE\-386377