ULevelStreaming::SetShouldBeVisible での表示切替による不具合について

This question was created in reference to: [Build lighting data missing after setting level invisible and then visible again in a packaged [Content removed]

<br/>

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

<br/>

参照元で報告されているものと同様 SetShouldBeVisible によるサブレベルの表示制御を行った際、

パッケージでのみレベルの見た目が変わってしまう現象が発生しています。

<br/>

UE-295719 にて Target Fix が 5.8 になっているようなのですが、

こちら 5.7.2 でのワークアラウンドの詳細、もしくは、適応可能な CL などはございますでしょうか?

<br/>

宜しくお願い致します。

[Attachment Removed]

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

本件、ご迷惑をおかけしております。

現在のところ、正式な修正には至っておらず、適用可能なCLはございませんが、ご案内可能なワークアラウンドがあります。

リンク先のEPSスレッドでは、表示切替時に関連するGUIDが正しく取得できなくなり、ライトデータが紐づけられなくなることから、正常にデータが掴めているうちにそれをキャッシュしておくワークアラウンドが提唱されておりました。今回ご紹介するワークアラウンドは、関連GUIDが取得できなかった際にライトデータの紐づけ更新を行わず(そのまま進行すると無効データと紐づけされるため)処理を打ち切るというアプローチで、結果的に前述のものとほぼ同様の効果が見込めます。

以下2か所ほどエンジンの改造が必要となります。

// Engine\Source\Runtime\Engine\Private\Components\LightComponent.cpp
// 256行目付近
 
void ULightComponentBase::ValidateLightGUIDs()
{
	// Validate light guids.
	if (!OriginalLightGuid.IsValid())
	{
		UpdateLightGUIDs();
	}
 
+	if (GetOwner() && !FActorInstanceGuid::GetActorInstanceGuid(*GetOwner()).IsValid())
+	{
+		return;
+	}
	
	LightGuid = (OriginalLightGuid.IsValid() && GetOwner() )? FGuid::Combine( OriginalLightGuid , FActorInstanceGuid::GetActorInstanceGuid(*GetOwner())) : FGuid();
}
 
void ULightComponentBase::UpdateLightGUIDs()
{
	if (HasStaticShadowing())
	{
#if WITH_EDITOR
		if (IsRunningCookCommandlet())
		{
			OriginalLightGuid = FGuid::NewDeterministicGuid(GetFullName());
		}
		else
#endif
		{
			OriginalLightGuid = FGuid::NewGuid();
		}
	}
	else
	{
		OriginalLightGuid = FGuid();
	}
 
+	if (GetOwner() && !FActorInstanceGuid::GetActorInstanceGuid(*GetOwner()).IsValid())
+	{
+		return;
+	}
 
	LightGuid = (OriginalLightGuid.IsValid() && GetOwner() )? FGuid::Combine( OriginalLightGuid , FActorInstanceGuid::GetActorInstanceGuid(*GetOwner())) : FGuid();
}
// Engine\Source\Runtime\Engine\Private\Components\StaticMeshComponent.cpp
// 3583行付近
 
void UStaticMeshComponent::UpdateMapBuildDataId()
{	
	if (GetOwner())	
	{
		//@todo_ow: Detect cases where MapBuildDataId has been successfully set on cook and skip?
		if (LODData.Num() && LODData[0].OriginalMapBuildDataId.IsValid())
		{
			FGuid ActorInstanceGuid = FActorInstanceGuid::GetActorInstanceGuid(*GetOwner());
 
+			if (!ActorInstanceGuid.IsValid())
+			{
+				return;
+			}
 
			// We already have a GUID, but in case of a LevelInstance Actor we must adjust it to be unique
			LODData[0].MapBuildDataId = FGuid::Combine(LODData[0].OriginalMapBuildDataId, ActorInstanceGuid);
			
			for (int i = 1; i < LODData.Num(); i++)
			{
				LODData[i].OriginalMapBuildDataId = GetMapDataIdForLOD(LODData[0].OriginalMapBuildDataId, i);
				LODData[i].MapBuildDataId = FGuid::Combine(LODData[i].OriginalMapBuildDataId, ActorInstanceGuid);
			}
		}
	}

これにより、リンク先のスレッドに投稿されていた再現プロジェクトで問題が起こらなくなることをUE5.7環境で確認済みです。ただし、本来であればGUIDのロストが起こらないよう対応するのが本筋であることを考えますと、あくまでも暫定回避策にすぎません。利用条件によって不具合や抜け漏れが生じないかなどをご確認のうえ、導入をご検討いただけますと幸いです。

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

[Attachment Removed]

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

修正方法のご提示ありがとうございます。

プロジェクト側で試してみて結果をご共有致します。

[Attachment Removed]

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

プロジェクト側で試してみたところ、サブレベルの表示制御を行っている箇所にて今回の問題が改善していることを確認致しました。

​> 利用条件によって不具合や抜け漏れが生じないか

様子見しつつ、また何かありましたらご相談させて頂けますと幸いです。​

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

[Attachment Removed]

ご確認ありがとうございました。

それでは本件は対応済みとしてCloseさせていただきます。

また何かありましたら、お気軽にご相談ください。

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

[Attachment Removed]