I’m researching how to dynamically generate a Landscape, and I’m stuck at the first step. After dynamically generating a LandscapeActor
, I encounter issues when creating and registering a LandscapeComponent
. The process halts at the registration step due to an unavoidable FTextureSourceIsValid
check, which always fails and causes a crash. Does anyone know the reason behind this? How can I correctly create and add a LandscapeComponent
dynamically?
Thank you!
Here is the code:
void UBPC_PWG::Create_Landscape_Component(FS_Landscape_Param Landscape_Params, ALandscape* Landscape_Actor)
{
if (Landscape_Actor == nullptr) return;
Set_Landscape_Material(Landscape_Actor);
UMaterialInterface* Local_Material = Landscape_Actor->LandscapeMaterial;
if (Local_Material == nullptr) return;
//转换为材质实例Constant
UMaterialInstanceConstant* Local_Material_Constant = Cast<UMaterialInstanceConstant>(Local_Material);
if (Local_Material_Constant == nullptr) return;
/*
UMaterialInstanceDynamic* Local_Material_Dynamic = UKismetMaterialLibrary::CreateDynamicMaterialInstance(GetWorld(), Local_Material);
if (Local_Material_Constant == nullptr) return;
*/
FVector Local_Landscape_Location = Landscape_Actor->GetActorLocation();
ULandscapeComponent* Local_Component = nullptr;
TArray<ULandscapeComponent*> LandscapeComponents;
ALandscapeStreamingProxy* Local_Stream_Proxy = nullptr;
ULandscapeInfo* Local_Land_Info = nullptr;
int Component_Size_Quads = Landscape_Params.Subsection_Size_Quads - 1;
int NumComponentsX = Landscape_Params.Num_Components;
int NumComponentsY = Landscape_Params.Num_Components;
int NumSubsections = Landscape_Params.Num_Subsections;
int SubsectionSizeQuads = Component_Size_Quads;
for (int y = 0; y < NumComponentsY; y++)
{
for (int x = 0; x < NumComponentsX; x++)
{
Local_Component = NewObject<ULandscapeComponent>(Landscape_Actor);
if (Local_Component == nullptr) continue;
Local_Stream_Proxy = NewObject<ALandscapeStreamingProxy>(GetWorld());
if (Local_Stream_Proxy == nullptr) continue;
Local_Stream_Proxy->SetActorScale3D(FVector(100.0f,100.0f,100.0f));
Local_Stream_Proxy->SetActorLocation(FVector(x * Component_Size_Quads + Local_Landscape_Location.X, y * Component_Size_Quads + Local_Landscape_Location.Y, 0.0f));
Local_Stream_Proxy->SetActorRotation(FRotator(0.0f, 0.0f, 0.0f));
Local_Stream_Proxy->SetLandscapeGuid(Landscape_Actor->GetLandscapeGuid());
Local_Stream_Proxy->SetLandscapeActor(Landscape_Actor);
Local_Stream_Proxy->LandscapeSectionOffset = FIntPoint(x * Component_Size_Quads, y * Component_Size_Quads);
if (Local_Stream_Proxy->GetRootComponent() == nullptr)
{
USceneComponent* RootComponent = NewObject<USceneComponent>(Local_Stream_Proxy);
if (RootComponent == nullptr) continue;
Local_Stream_Proxy->SetRootComponent(RootComponent);
RootComponent->RegisterComponent();
}
Local_Stream_Proxy->LandscapeMaterial = Local_Material_Constant;
Local_Stream_Proxy->PostEditChange();
Local_Component->SetRelativeLocation(FVector(x * Component_Size_Quads, y * Component_Size_Quads, 0.0f));
Local_Component->SetSectionBase(FIntPoint(x * Component_Size_Quads, y * Component_Size_Quads));
Local_Component->NumSubsections = NumSubsections;
Local_Component->SubsectionSizeQuads = SubsectionSizeQuads;
//Local_Component->MaterialInstances.Add(Local_Material_Constant);
//if (!Local_Component->GetMaterial(0)) continue;
Local_Component->SetMaterial(0,Local_Material_Constant);
if (!Local_Component->GetMaterial(0)) continue;
Local_Component->SetupAttachment(Local_Stream_Proxy->GetRootComponent());
Local_Component->Init(x * Component_Size_Quads, y * Component_Size_Quads, Component_Size_Quads, NumSubsections, SubsectionSizeQuads);
Local_Component->PostEditChange();
//this question
Local_Component->RegisterComponent();
Local_Stream_Proxy->LandscapeComponents.Add(Local_Component);
Local_Stream_Proxy->RegisterAllComponents();
Local_Stream_Proxy->AddToRoot();
Local_Land_Info = Landscape_Actor->GetLandscapeInfo();
if (Local_Land_Info)
{
Local_Land_Info->RegisterActor(Local_Stream_Proxy, true, true);
}
}
}
}